Adding Dropdown in all places.

This commit is contained in:
Kartik Sharma 2025-12-06 12:58:43 +05:30
parent c7e72946ea
commit 654e34ebfa
40 changed files with 573 additions and 487 deletions

View File

@ -43,7 +43,7 @@ const BucketForm = ({ selectedBucket, mode, onSubmit, onCancel, isPending }) =>
Name Name
</Label> </Label>
<input <input
className="form-control form-control-sm" className="form-control"
{...register("name")} {...register("name")}
/> />
{errors.name && ( {errors.name && (
@ -51,12 +51,12 @@ const BucketForm = ({ selectedBucket, mode, onSubmit, onCancel, isPending }) =>
)} )}
</div> </div>
<div className="mb-3"> <div className="my-3">
<Label htmlFor="description" className="text-start" required> <Label htmlFor="description" className="text-start" required>
Description Description
</Label> </Label>
<textarea <textarea
className="form-control form-control-sm" className="form-control"
{...register("description")} {...register("description")}
rows="3" rows="3"
/> />

View File

@ -14,7 +14,7 @@ const BucketList = ({ buckets, loading, searchTerm, onEdit, onDelete }) => {
if (!loading && sorted.length === 0) return <div>No buckets found</div>; if (!loading && sorted.length === 0) return <div>No buckets found</div>;
return ( return (
<div className="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3 pt-3 px-2 px-sm-0"> <div className="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3 pt-3 px-2 px-sm-0 text-start">
{sorted.map((bucket) => ( {sorted.map((bucket) => (
<div className="col" key={bucket.id}> <div className="col" key={bucket.id}>
<div className="card h-100"> <div className="card h-100">

View File

@ -40,7 +40,7 @@ const CardViewContact = ({
className="card text-start border-1" className="card text-start border-1"
style={{ background: `${!IsActive ? "#f8f6f6" : ""}` }} style={{ background: `${!IsActive ? "#f8f6f6" : ""}` }}
> >
<div className="card-body px-1 py-2 pb-0"> <div className="card-body px-1 py-2 pb-0">
<div className="d-flex justify-content-between"> <div className="d-flex justify-content-between">
<div <div
className={`d-flex align-items-center ${ className={`d-flex align-items-center ${
@ -61,7 +61,7 @@ const CardViewContact = ({
(contact?.name || "").trim().split(" ")[1]?.charAt(0) || "" (contact?.name || "").trim().split(" ")[1]?.charAt(0) || ""
} }
/>{" "} />{" "}
<span className="text-heading fs-6 ms-2"> {contact?.name}</span> <span className="text-heading fs-6 ms-2 mt-n1"> {contact?.name}</span>
</div> </div>
<div> <div>
{IsActive && ( {IsActive && (

View File

@ -45,7 +45,7 @@ const ManageBucket1 = () => {
return ( return (
<div className="container m-0 p-0" style={{ minHeight: "00px" }}> <div className="container m-0 p-0" style={{ minHeight: "00px" }}>
<div className="d-flex justify-content-center"> <div className="d-flex justify-content-center">
<p className="fs-5 fw-semibold m-0">Manage Buckets</p> <h5 className="m-0">Manage Buckets</h5>
</div> </div>
{action ? ( {action ? (

View File

@ -281,7 +281,7 @@ const ManageContact = ({ contactId, closeModal }) => {
]} ]}
placeholder="Choose a Label" placeholder="Choose a Label"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}
@ -295,7 +295,7 @@ const ManageContact = ({ contactId, closeModal }) => {
</small> </small>
)} )}
</div> </div>
<div className="col-7 text-start mt-n3"> <div className="col-7 text-start mt-n0">
<label className="form-label">Email</label> <label className="form-label">Email</label>
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<input <input
@ -344,7 +344,7 @@ const ManageContact = ({ contactId, closeModal }) => {
]} ]}
placeholder="Choose a Label" placeholder="Choose a Label"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}
@ -359,7 +359,7 @@ const ManageContact = ({ contactId, closeModal }) => {
)} )}
</div> </div>
<div className="col-7 text-start mt-n3"> <div className="col-7 text-start mt-n0">
<label className="form-label">Phone</label> <label className="form-label">Phone</label>
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<input <input
@ -406,7 +406,7 @@ const ManageContact = ({ contactId, closeModal }) => {
required required
options={contactCategory ?? []} options={contactCategory ?? []}
placeholder="Select Category" placeholder="Select Category"
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}

View File

@ -252,7 +252,7 @@ const ManageDocument = ({ closeModal, Document_Entity, Entity }) => {
options={DocumentCategories ?? []} options={DocumentCategories ?? []}
placeholder="Select Category" placeholder="Select Category"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}
@ -282,7 +282,7 @@ const ManageDocument = ({ closeModal, Document_Entity, Entity }) => {
options={DocumentTypes ?? []} options={DocumentTypes ?? []}
placeholder="Select Document Type" placeholder="Select Document Type"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}

View File

@ -529,7 +529,7 @@ const ManageEmployee = ({ employeeId, onClosed }) => {
a?.name?.localeCompare(b?.name) a?.name?.localeCompare(b?.name)
)} )}
placeholder="Select Role" placeholder="Select Role"
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}

View File

@ -255,7 +255,7 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
options={organizationList ?? []} options={organizationList ?? []}
placeholder="--Select Organization--" placeholder="--Select Organization--"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value || ""} value={field.value || ""}
onChange={field.onChange} onChange={field.onChange}
@ -281,7 +281,7 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
options={serviceList ?? []} options={serviceList ?? []}
placeholder="--Select Service--" placeholder="--Select Service--"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value || ""} value={field.value || ""}
onChange={field.onChange} onChange={field.onChange}

View File

@ -261,7 +261,7 @@ const ManageProjectInfo = ({ project, onClose }) => {
)} )}
</div> </div>
<div className="col-12 mt-n1"> <div className="col-12">
<Label htmlFor="promoterId" className="form-label"> <Label htmlFor="promoterId" className="form-label">
Promoter Promoter
</Label> </Label>
@ -296,7 +296,7 @@ const ManageProjectInfo = ({ project, onClose }) => {
)} )}
</div> </div>
<div className="col-12 mt-n1"> <div className="col-12">
<Label htmlFor="pmcId" className="form-label"> <Label htmlFor="pmcId" className="form-label">
PMC PMC
</Label> </Label>
@ -331,7 +331,7 @@ const ManageProjectInfo = ({ project, onClose }) => {
)} )}
</div> </div>
<div className="d-flex justify-content-between text-secondary text-tiny text-wrap mt-n1"> <div className="d-flex justify-content-between text-secondary text-tiny text-wrap">
<span> <span>
<i className="bx bx-sm bx-info-circle"></i> Not found PMC and <i className="bx bx-sm bx-info-circle"></i> Not found PMC and
Pomoter, find through SPRID or create new Pomoter, find through SPRID or create new

View File

@ -142,7 +142,7 @@ const ProjectPermission = () => {
} }
placeholder="-- Select Employee --" placeholder="-- Select Employee --"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}

View File

@ -2,8 +2,11 @@ import React, { useState } from "react";
import TeamEmployeeList from "./TeamEmployeeList"; import TeamEmployeeList from "./TeamEmployeeList";
import { useOrganization } from "../../../hooks/useDirectory"; import { useOrganization } from "../../../hooks/useDirectory";
import { useOrganizationsList } from "../../../hooks/useOrganization"; import { useOrganizationsList } from "../../../hooks/useOrganization";
import { useProjectAssignedOrganizationsName } from "../../../hooks/useProjects"; import { useProjectAssignedOrganizationsName } from "../../../hooks/useProjects";
import { useSelectedProject } from "../../../slices/apiDataManager"; import { useSelectedProject } from "../../../slices/apiDataManager";
import { AppFormController } from "../../../hooks/appHooks/useAppForm";
import SelectField from "../../common/Forms/SelectField";
import { useForm } from "react-hook-form";
const TeamAssignToProject = ({ closeModal }) => { const TeamAssignToProject = ({ closeModal }) => {
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
@ -11,54 +14,48 @@ const TeamAssignToProject = ({ closeModal }) => {
const project = useSelectedProject(); const project = useSelectedProject();
const { data, isLoading, isError, error } = const { data, isLoading, isError, error } =
useProjectAssignedOrganizationsName(project); useProjectAssignedOrganizationsName(project);
const { control, watch, formState: { errors } } = useForm({
defaultValues: { organizationId: "" },
});
return ( return (
<div className="container"> <div className="container">
{/* <p className="fs-5 fs-seminbod ">Assign Employee To Project </p> */} {/* <p className="fs-5 fs-seminbod ">Assign Employee To Project </p> */}
<h5 className="mb-4">Assign Employee To Project</h5> <h5 className="mb-4">Assign Employee To Project</h5>
<div className="row align-items-center gx-5"> <div className="row align-items-center gx-5 text-start">
<div className="col"> <div className="col-12 col-md-6 mb-2">
<div className="d-flex flex-grow-1 align-items-center gap-2"> <AppFormController
{isLoading ? ( name="organizationId"
<select className="form-select form-select-sm w-100" disabled> control={control}
<option value="">Loading...</option> rules={{ required: "Organization is required" }}
</select> render={({ field }) => (
) : data?.length === 0 ? ( <SelectField
<p className="mb-0 badge bg-label-secondary">No organizations found</p> label="Select Organization"
) : ( options={data ?? []}
<> placeholder="Choose an Organization"
<label required
htmlFor="organization" labelKey="name"
className="form-label mb-0 text-nowrap" valueKey="id"
> value={field.value}
Select Organization onChange={field.onChange}
</label> isLoading={isLoading}
<select className="m-0 w-100"
id="organization" />
className="form-select form-select-sm w-100" )}
value={selectedOrg || ""} />
onChange={(e) => setSelectedOrg(e.target.value)} {errors.organizationId && (
> <small className="danger-text">{errors.organizationId.message}</small>
<option value="">Select</option>
{data.map((org) => (
<option key={org.id} value={org.id}>
{org.name}
</option>
))}
</select>
</>
)} )}
</div> </div>
</div> <div className="col-12 col-md-6 mt-n5">
<div className="col"> <div className="d-flex flex-column">
<div className="d-flex flex-grow-1 align-items-center gap-2"> <label htmlFor="search" className="form-label mb-1">
<label htmlFor="search" className="form-label mb-0 text-nowrap">
Search Employee Search Employee
</label> </label>
<input <input
id="search" id="search"
type="search" type="search"
className="form-control form-control-sm w-100" className="form-control w-100"
placeholder="Search..." placeholder="Search..."
value={searchText} value={searchText}
onChange={(e) => setSearchText(e.target.value)} onChange={(e) => setSearchText(e.target.value)}

View File

@ -22,6 +22,9 @@ import { useSelectedProject } from "../../../slices/apiDataManager";
import GlobalModel from "../../common/GlobalModel"; import GlobalModel from "../../common/GlobalModel";
import TeamAssignToProject from "./TeamAssignToProject"; import TeamAssignToProject from "./TeamAssignToProject";
import { SpinnerLoader } from "../../common/Loader"; import { SpinnerLoader } from "../../common/Loader";
import { AppFormController } from "../../../hooks/appHooks/useAppForm";
import SelectField from "../../common/Forms/SelectField";
import { useForm } from "react-hook-form";
const Teams = () => { const Teams = () => {
const selectedProject = useSelectedProject(); const selectedProject = useSelectedProject();
@ -30,9 +33,15 @@ const Teams = () => {
const [employees, setEmployees] = useState([]); const [employees, setEmployees] = useState([]);
const [selectedEmployee, setSelectedEmployee] = useState(null); const [selectedEmployee, setSelectedEmployee] = useState(null);
const [deleteEmployee, setDeleteEmplyee] = useState(null); const [deleteEmployee, setDeleteEmplyee] = useState(null);
const [searchTerm, setSearchTerm] = useState(""); // State for search term
const [selectedService, setSelectedService] = useState(null);
const [activeEmployee, setActiveEmployee] = useState(false); const [activeEmployee, setActiveEmployee] = useState(false);
const { control, watch } = useForm({
defaultValues: {
selectedService: "",
searchTerm: "",
},
});
const selectedService = watch("selectedService");
const searchTerm = watch("searchTerm");
const { data: assignedServices, isLoading: servicesLoading } = const { data: assignedServices, isLoading: servicesLoading } =
useProjectAssignedServices(selectedProject); useProjectAssignedServices(selectedProject);
@ -95,26 +104,23 @@ const Teams = () => {
const filteredEmployees = useMemo(() => { const filteredEmployees = useMemo(() => {
if (!projectEmployees) return []; if (!projectEmployees) return [];
let filtered = projectEmployees; let filtered = projectEmployees;
if (activeEmployee) { if (activeEmployee) {
filtered = projectEmployees.filter((emp) => !emp.isActive); filtered = projectEmployees.filter((emp) => !emp.isActive);
} }
// Apply search filter if present
if (searchTerm?.trim()) { if (searchTerm?.trim()) {
const lower = searchTerm.toLowerCase(); const lower = searchTerm.toLowerCase();
filtered = filtered.filter((emp) => { filtered = filtered.filter((emp) => {
const fullName = `${emp.firstName ?? ""} ${emp.lastName ?? ""}`.toLowerCase(); const fullName = `${emp.firstName ?? ""} ${emp.lastName ?? ""}`.toLowerCase();
const jobRole = getJobRole(emp?.jobRoleId)?.toLowerCase(); return fullName.includes(lower) || (emp.jobRoleName ?? "").toLowerCase().includes(lower);
return fullName.includes(lower) || jobRole.includes(lower);
}); });
} }
return filtered; return filtered;
}, [projectEmployees, searchTerm, activeEmployee]); }, [projectEmployees, searchTerm, activeEmployee]);
const handleSearch = (e) => setSearchTerm(e.target.value);
const employeeHandler = useCallback( const employeeHandler = useCallback(
(msg) => { (msg) => {
if (filteredEmployees.some((emp) => emp.employeeId == msg.employeeId)) { if (filteredEmployees.some((emp) => emp.employeeId == msg.employeeId)) {
@ -124,6 +130,7 @@ const Teams = () => {
[filteredEmployees, refetch] [filteredEmployees, refetch]
); );
useEffect(() => { useEffect(() => {
eventBus.on("employee", employeeHandler); eventBus.on("employee", employeeHandler);
return () => eventBus.off("employee", employeeHandler); return () => eventBus.off("employee", employeeHandler);
@ -154,62 +161,68 @@ const Teams = () => {
<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 align-items-center justify-content-between mb-4 g-3"> <div className="row align-items-center justify-content-between mb-4 g-3">
<div className="col-md-6 col-12 algin-items-center"> <div className="col-md-6 col-12 d-flex flex-wrap align-items-center gap-3">
<div className="d-flex flex-wrap align-items-center gap-3"> {!servicesLoading && assignedServices && (
<div> <>
{!servicesLoading && ( {assignedServices.length === 1 && (
<> <h5 className="mb-2">{assignedServices[0].name}</h5>
{assignedServices?.length === 1 && (
<h5 className="mb-2">{assignedServices[0].name}</h5>
)}
{assignedServices?.length > 1 && (
<select
className="form-select form-select-sm"
aria-label="Select Service"
value={selectedService}
onChange={handleServiceChange}
>
<option value="">All Services</option>
{assignedServices.map((service) => (
<option key={service.id} value={service.id}>
{service.name}
</option>
))}
</select>
)}
</>
)} )}
</div>
<div className="form-check form-switch d-flex align-items-center text-nowrap"> {assignedServices.length > 1 && (
<input <div className="col-12 col-md-6 mb-2 text-start">
type="checkbox" <AppFormController
className="form-check-input" name="selectedService"
id="activeEmployeeSwitch" control={control}
checked={activeEmployee} render={({ field }) => (
onChange={handleToggleActive} <SelectField
/> label="Select Service"
<label options={[{ id: "", name: "All Services" }, ...assignedServices]}
className="form-check-label ms-2" placeholder="Choose a Service"
htmlFor="activeEmployeeSwitch" labelKey="name"
> valueKey="id"
{activeEmployee ? "Active Employees" : "In-active Employees"} value={field.value}
</label> onChange={field.onChange}
</div> isLoading={servicesLoading}
className="w-100"
/>
)}
/>
</div>
)}
</>
)}
<div className="form-check form-switch d-flex align-items-center text-nowrap">
<input
type="checkbox"
className="form-check-input"
id="activeEmployeeSwitch"
checked={activeEmployee}
onChange={handleToggleActive}
/>
<label className="form-check-label ms-2" htmlFor="activeEmployeeSwitch">
{activeEmployee ? "Active Employees" : "In-active Employees"}
</label>
</div> </div>
</div> </div>
<div className="col-md-6 col-12 d-flex justify-content-md-end align-items-center justify-content-start gap-3"> <div className="col-md-6 col-12 d-flex justify-content-md-end align-items-center justify-content-start gap-3 mt-n1">
<input <div className="col-12 col-md-4">
type="search" <AppFormController
className="form-control form-control-sm" name="searchTerm"
placeholder="Search by Name or Role" control={control}
aria-controls="DataTables_Table_0" render={({ field }) => (
style={{ maxWidth: "200px" }} <input
value={searchTerm} type="search"
onChange={handleSearch} className="form-control form-control-sm w-100"
/> placeholder="Search by Name or Role"
value={field.value}
onChange={field.onChange}
/>
)}
/>
</div>
{HasAssignUserPermission && ( {HasAssignUserPermission && (
<button <button
@ -246,74 +259,73 @@ const Teams = () => {
</tr> </tr>
</thead> </thead>
<tbody className="table-border-bottom-0"> <tbody className="table-border-bottom-0">
{filteredEmployees && {filteredEmployees
filteredEmployees .sort((a, b) =>
.sort((a, b) => (a.firstName || "").localeCompare(b.firstName || "")
(a.firstName || "").localeCompare(b.firstName || "") )
) .map((emp) => (
.map((emp) => ( <tr key={emp.id}>
<tr key={emp.id}> <td>
<td> <div className="d-flex justify-content-start align-items-center">
<div className="d-flex justify-content-start align-items-center"> <Avatar
<Avatar firstName={emp.firstName}
firstName={emp.firstName} lastName={emp.lastName}
lastName={emp.lastName} />
/> <div className="d-flex flex-column">
<div className="d-flex flex-column"> <a
<a onClick={() =>
onClick={() => navigate(
navigate( `/employee/${emp.employeeId}?for=attendance`
`/employee/${emp.employeeId}?for=attendance` )
) }
} className="text-heading text-truncate cursor-pointer"
className="text-heading text-truncate cursor-pointer"
>
<span className="fw-normal">
{emp.firstName}{" "}
{emp.lastName}
</span>
</a>
</div>
</div>
</td>
<td>{emp.serviceName || "N/A"}</td>
<td>{emp.organizationName || "N/A"}</td>
<td>
{moment(emp.allocationDate).format("DD-MMM-YYYY")}
</td>
{activeEmployee && (
<td>
{emp.reAllocationDate
? moment(emp.reAllocationDate).format(
"DD-MMM-YYYY"
)
: "Present"}
</td>
)}
<td>
<span className="badge bg-label-primary me-1">
{getJobRole(emp.jobRoleId)}
</span>
</td>
<td>
{emp.isActive ? (
<button
aria-label="Delete"
type="button"
title="Remove from project"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() => setSelectedEmployee(emp)}
> >
<i className="bx bx-trash me-1 text-danger"></i> <span className="fw-normal">
</button> {emp.firstName}{" "}
) : ( {emp.lastName}
<span>Not in project</span> </span>
)} </a>
</div>
</div>
</td>
<td>{emp.serviceName || "N/A"}</td>
<td>{emp.organizationName || "N/A"}</td>
<td>
{moment(emp.allocationDate).format("DD-MMM-YYYY")}
</td>
{activeEmployee && (
<td>
{emp.reAllocationDate
? moment(emp.reAllocationDate).format(
"DD-MMM-YYYY"
)
: "Present"}
</td> </td>
</tr> )}
))} <td>
<span className="badge bg-label-primary me-1">
{getJobRole(emp.jobRoleId)}
</span>
</td>
<td>
{emp.isActive ? (
<button
aria-label="Delete"
type="button"
title="Remove from project"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() => setSelectedEmployee(emp)}
>
<i className="bx bx-trash me-1 text-danger"></i>
</button>
) : (
<span>Not in project</span>
)}
</td>
</tr>
))}
</tbody> </tbody>
</table> </table>
)} )}

View File

@ -135,7 +135,7 @@ const ManageServiceProject = ({ serviceProjectId, onClose }) => {
options={organization?.data ?? []} options={organization?.data ?? []}
placeholder="Select Client" placeholder="Select Client"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}
@ -147,7 +147,7 @@ const ManageServiceProject = ({ serviceProjectId, onClose }) => {
</div> </div>
<i <i
className="bx bx-plus-circle bx-xs cursor-pointer text-primary mt-n3" className="bx bx-plus-circle bx-xs cursor-pointer text-primary "
onClick={() => { onClick={() => {
onClose(); onClose();
openOrgModal({ startStep: 2 }); openOrgModal({ startStep: 2 });
@ -317,7 +317,7 @@ const ManageServiceProject = ({ serviceProjectId, onClose }) => {
)} )}
</div> </div>
</div> </div>
<div className="d-flex justify-content-end gap-4 mt-4"> <div className="d-flex justify-content-end gap-2 mt-4">
<button <button
className="btn btn-sm btn-outline-secondary" className="btn btn-sm btn-outline-secondary"
disabled={isPending || isUpdating} disabled={isPending || isUpdating}

View File

@ -68,7 +68,7 @@ const ChangeStatus = ({ statusId, projectId, jobId, popUpId }) => {
options={data ?? []} options={data ?? []}
placeholder="Choose a Status" placeholder="Choose a Status"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}

View File

@ -236,8 +236,8 @@ const ManageJob = ({ Job }) => {
options={data ?? []} options={data ?? []}
placeholder="Choose a Status" placeholder="Choose a Status"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}
isLoading={isLoading} isLoading={isLoading}

View File

@ -32,7 +32,7 @@ const ContactInfro = ({ onNext }) => {
<input <input
id="firstName" id="firstName"
type="text" type="text"
className={`form-control form-control-sm`} className={`form-control `}
{...register("firstName")} {...register("firstName")}
/> />
{errors.firstName && ( {errors.firstName && (
@ -46,7 +46,7 @@ const ContactInfro = ({ onNext }) => {
<input <input
id="lastName" id="lastName"
type="text" type="text"
className={`form-control form-control-sm `} className={`form-control `}
{...register("lastName")} {...register("lastName")}
/> />
{errors.lastName && ( {errors.lastName && (
@ -60,7 +60,7 @@ const ContactInfro = ({ onNext }) => {
<input <input
id="email" id="email"
type="email" type="email"
className={`form-control form-control-sm `} className={`form-control `}
{...register("email")} {...register("email")}
/> />
{errors.email && ( {errors.email && (
@ -74,7 +74,7 @@ const ContactInfro = ({ onNext }) => {
<input <input
id="contactNumber" id="contactNumber"
type="text" type="text"
className={`form-control form-control-sm `} className={`form-control `}
{...register("contactNumber")} {...register("contactNumber")}
inputMode="tel" inputMode="tel"
placeholder="+91 9876543210" placeholder="+91 9876543210"

View File

@ -7,6 +7,8 @@ import { LogoUpload } from './LogoUpload';
import showToast from '../../services/toastService'; import showToast from '../../services/toastService';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { EditTenant } from './TenantSchema'; import { EditTenant } from './TenantSchema';
import { AppFormController } from '../../hooks/appHooks/useAppForm';
import SelectField from '../common/Forms/SelectField';
const EditProfile = ({ TenantId, onClose }) => { const EditProfile = ({ TenantId, onClose }) => {
const { data, isLoading, isError, error } = useTenantDetails(TenantId); const { data, isLoading, isError, error } = useTenantDetails(TenantId);
@ -37,7 +39,7 @@ const EditProfile = ({ TenantId, onClose }) => {
} }
}); });
const { register, reset, handleSubmit, formState: { errors } } = methods; const { register, control, reset, handleSubmit, formState: { errors } } = methods;
const onSubmit = (formData) => { const onSubmit = (formData) => {
const tenantPayload = { ...formData, contactName: `${formData.firstName} ${formData.lastName}`, id: data.id, } const tenantPayload = { ...formData, contactName: `${formData.firstName} ${formData.lastName}`, id: data.id, }
@ -74,93 +76,122 @@ const EditProfile = ({ TenantId, onClose }) => {
<form className="row g-6" onSubmit={handleSubmit(onSubmit)}> <form className="row g-6" onSubmit={handleSubmit(onSubmit)}>
<h5>Edit Tenant</h5> <h5>Edit Tenant</h5>
<div className="col-sm-6 mt-1 text-start"> <div className="col-sm-6 mt-n2 text-start">
<Label htmlFor="firstName" required>First Name</Label> <Label htmlFor="firstName" required>First Name</Label>
<input id="firstName" type="text" className="form-control form-control-sm" {...register("firstName")} inputMode='text' /> <input id="firstName" type="text" className="form-control " {...register("firstName")} inputMode='text' />
{errors.firstName && <div className="danger-text">{errors.firstName.message}</div>} {errors.firstName && <div className="danger-text">{errors.firstName.message}</div>}
</div> </div>
<div className="col-sm-6 mt-1 text-start"> <div className="col-sm-6 mt-n2 text-start">
<Label htmlFor="lastName" required>Last Name</Label> <Label htmlFor="lastName" required>Last Name</Label>
<input id="lastName" type="text" className="form-control form-control-sm" {...register("lastName")} /> <input id="lastName" type="text" className="form-control " {...register("lastName")} />
{errors.lastName && <div className="danger-text">{errors.lastName.message}</div>} {errors.lastName && <div className="danger-text">{errors.lastName.message}</div>}
</div> </div>
<div className="col-sm-6 mt-1 text-start"> <div className="col-sm-6 text-start">
<Label htmlFor="contactNumber" required>Contact Number</Label> <Label htmlFor="contactNumber" required>Contact Number</Label>
<input id="contactNumber" type="text" className="form-control form-control-sm" {...register("contactNumber")} inputMode="tel" <input id="contactNumber" type="text" className="form-control " {...register("contactNumber")} inputMode="tel"
placeholder="+91 9876543210" /> placeholder="+91 9876543210" />
{errors.contactNumber && <div className="danger-text">{errors.contactNumber.message}</div>} {errors.contactNumber && <div className="danger-text">{errors.contactNumber.message}</div>}
</div> </div>
<div className="col-sm-6 mt-1 text-start"> <div className="col-sm-6 text-start">
<Label htmlFor="domainName" >Domain Name</Label> <Label htmlFor="domainName" >Domain Name</Label>
<input id="domainName" type="text" className="form-control form-control-sm" {...register("domainName")} /> <input id="domainName" type="text" className="form-control " {...register("domainName")} />
{errors.domainName && <div className="danger-text">{errors.domainName.message}</div>} {errors.domainName && <div className="danger-text">{errors.domainName.message}</div>}
</div> </div>
<div className="col-sm-6 mt-1 text-start"> <div className="col-sm-6 text-start">
<Label htmlFor="taxId" >Tax ID</Label> <Label htmlFor="taxId" >Tax ID</Label>
<input id="taxId" type="text" className="form-control form-control-sm" {...register("taxId")} /> <input id="taxId" type="text" className="form-control " {...register("taxId")} />
{errors.taxId && <div className="danger-text">{errors.taxId.message}</div>} {errors.taxId && <div className="danger-text">{errors.taxId.message}</div>}
</div> </div>
<div className="col-sm-6 mt-1 text-start"> <div className="col-sm-6 text-start">
<Label htmlFor="officeNumber" >Office Number</Label> <Label htmlFor="officeNumber" >Office Number</Label>
<input id="officeNumber" type="text" className="form-control form-control-sm" {...register("officeNumber")} /> <input id="officeNumber" type="text" className="form-control " {...register("officeNumber")} />
{errors.officeNumber && <div className="danger-text">{errors.officeNumber.message}</div>} {errors.officeNumber && <div className="danger-text">{errors.officeNumber.message}</div>}
</div> </div>
<div className="col-sm-6 mt-1 text-start">
<Label htmlFor="industryId" required>Industry</Label>
<select className="form-select form-select-sm" {...register("industryId")}>
{industryLoading ? <option value="">Loading...</option> :
Industries?.map((indu) => (
<option key={indu.id} value={indu.id}>{indu.name}</option>
))
}
</select>
{errors.industryId && <div className="danger-text">{errors.industryId.message}</div>}
</div>
<div className="col-sm-6 mt-1 text-start">
<Label htmlFor="reference">Reference</Label>
<select className="form-select form-select-sm" {...register("reference")}>
{reference.map((org) => (
<option key={org.val} value={org.val}>{org.name}</option>
))}
</select>
{errors.reference && <div className="danger-text">{errors.reference.message}</div>}
</div>
<div className="col-sm-6 text-start"> <div className="col-sm-6 text-start">
<Label htmlFor="organizationSize" required> <AppFormController
Organization Size name="industryId"
</Label> control={control}
render={({ field }) => (
<SelectField
label="Industry"
options={Industries ?? []}
placeholder={industryLoading ? "Loading..." : "Choose an Industry"}
required
labelKey="name"
valueKey="id"
value={field.value}
onChange={field.onChange}
isLoading={industryLoading}
className="m-0 w-100"
/>
)}
/>
<select {errors.industryId && (
className="form-select form-select-sm" <small className="danger-text">{errors.industryId.message}</small>
{...register("organizationSize")}
>
{orgSize.map((org) => (
<option key={org.val} value={org.val}>
{org.name}
</option>
))}
</select>
{errors.organizationSize && (
<div className="danger-text">{errors.organizationSize.message}</div>
)} )}
</div> </div>
<div className="col-12 mt-1 text-start">
<div className="col-sm-6 text-start">
<AppFormController
name="reference"
control={control}
render={({ field }) => (
<SelectField
label="Reference"
placeholder="Select Reference"
options={reference ?? []}
labelKey="name"
valueKey="val"
value={field.value}
onChange={field.onChange}
className="shadow-none border py-1 px-2 small m-0"
/>
)}
/>
{errors.reference && (
<small className="danger-text">{errors.reference.message}</small>
)}
</div>
<div className="col-sm-6 text-start">
<AppFormController
name="organizationSize"
control={control}
render={({ field }) => (
<SelectField
label="Organization Size"
placeholder="Select Organization Size"
options={orgSize ?? []}
labelKey="name"
valueKey="val"
value={field.value}
onChange={field.onChange}
className="shadow-none border py-1 px-2 small m-0"
required
/>
)}
/>
{errors.organizationSize && (
<small className="danger-text">{errors.organizationSize.message}</small>
)}
</div>
<div className="col-12 text-start">
<Label htmlFor="billingAddress" required>Billing Address</Label> <Label htmlFor="billingAddress" required>Billing Address</Label>
<textarea id="billingAddress" className="form-control" {...register("billingAddress")} rows={2} /> <textarea id="billingAddress" className="form-control" {...register("billingAddress")} rows={2} />
{errors.billingAddress && <div className="danger-text">{errors.billingAddress.message}</div>} {errors.billingAddress && <div className="danger-text">{errors.billingAddress.message}</div>}
</div> </div>
<div className="col-12 mt-1 text-start"> <div className="col-12 text-start">
<Label htmlFor="description">Description</Label> <Label htmlFor="description">Description</Label>
<textarea id="description" className="form-control" {...register("description")} rows={2} /> <textarea id="description" className="form-control" {...register("description")} rows={2} />
{errors.description && <div className="danger-text">{errors.description.message}</div>} {errors.description && <div className="danger-text">{errors.description.message}</div>}

View File

@ -8,6 +8,9 @@ import { orgSize, reference } from "../../utils/constants";
import moment from "moment"; import moment from "moment";
import { useGlobalServices } from "../../hooks/masterHook/useMaster"; import { useGlobalServices } from "../../hooks/masterHook/useMaster";
import SelectMultiple from "../common/SelectMultiple"; import SelectMultiple from "../common/SelectMultiple";
import { AppFormController } from "../../hooks/appHooks/useAppForm";
import SelectField from "../common/Forms/SelectField";
import { fill } from "pdf-lib";
const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => { const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
const { data, isError, isLoading: industryLoading } = useIndustries(); const { data, isError, isLoading: industryLoading } = useIndustries();
@ -53,7 +56,8 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
// onSubmitTenant(data); // onSubmitTenant(data);
// onNext(); // onNext();
const tenantPayload = { ...data, onBoardingDate: moment.utc(data.onBoardingDate, "DD-MM-YYYY").toISOString() } const tenantPayload = { ...data, onBoardingDate: moment.utc(data.onBoardingDate, "DD-MM-YYYY").toISOString() }
CreateTenant(tenantPayload); // CreateTenant(tenantPayload);
console.log(tenantPayload)
} }
}; };
@ -67,7 +71,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
return ( return (
<div className="row g-2 text-start"> <div className="row g-6 text-start">
<div className="col-sm-6"> <div className="col-sm-6">
<Label htmlFor="organizationName" required> <Label htmlFor="organizationName" required>
Organization Name Organization Name
@ -75,7 +79,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
<input <input
id="organizationName" id="organizationName"
className={`form-control form-control-sm `} className={`form-control `}
{...register("organizationName")} {...register("organizationName")}
/> />
{errors.organizationName && ( {errors.organizationName && (
@ -89,7 +93,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</Label> </Label>
<input <input
id="officeNumber" id="officeNumber"
className={`form-control form-control-sm `} className={`form-control `}
{...register("officeNumber")} {...register("officeNumber")}
/> />
{errors.officeNumber && ( {errors.officeNumber && (
@ -103,7 +107,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</Label> </Label>
<input <input
id="domainName" id="domainName"
className={`form-control form-control-sm `} className={`form-control `}
{...register("domainName")} {...register("domainName")}
/> />
{errors.domainName && ( {errors.domainName && (
@ -117,7 +121,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</Label> </Label>
<input <input
id="taxId" id="taxId"
className={`form-control form-control-sm `} className={`form-control `}
{...register("taxId")} {...register("taxId")}
/> />
{errors.taxId && ( {errors.taxId && (
@ -131,6 +135,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</Label> </Label>
<DatePicker <DatePicker
name="onBoardingDate" name="onBoardingDate"
size="md"
control={control} control={control}
placeholder="DD-MM-YYYY" placeholder="DD-MM-YYYY"
maxDate={new Date()} maxDate={new Date()}
@ -143,73 +148,79 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
)} )}
</div> </div>
<div className="col-sm-6"> <div className="col-sm-6 mb-2 mb-md-4">
<Label htmlFor="organizationSize" required> <AppFormController
Organization Size name="organizationSize"
</Label> control={control}
render={({ field }) => (
<select <SelectField
id="organizationSize" label="Organization Size"
className="form-select shadow-none border py-1 px-2" placeholder="Select Organization Size"
style={{ fontSize: "0.875rem" }} // Bootstrap's small text size options={orgSize ?? []}
{...register("organizationSize", { required: "Organization size is required" })} labelKey="name"
> valueKey="val"
{orgSize.map((org) => ( value={field.value}
<option key={org.val} value={org.val}> onChange={field.onChange}
{org.name} className="shadow-none border py-1 px-2 small m-0"
</option> required
))} />
</select> )}
/>
{errors.organizationSize && ( {errors.organizationSize && (
<div className="danger-text">{errors.organizationSize.message}</div> <small className="danger-text">{errors.organizationSize.message}</small>
)} )}
</div> </div>
<div className="col-sm-6 mt-n3">
<div className="col-sm-6"> <AppFormController
<Label htmlFor="industryId" required> name="industryId"
Industry control={control} // make sure `control` comes from useForm
</Label> render={({ field }) => (
<select <SelectField
id="industryId" label="Industry"
className="form-select shadow-none border py-1 px-2 small" placeholder={industryLoading ? "Loading..." : "Select Industry"}
{...register("industryId")} options={data ?? []}
> labelKey="name"
{industryLoading ? ( valueKeyKey="id"
<option value="">Loading...</option> value={field.value}
) : ( onChange={field.onChange}
data?.map((indu) => ( isLoading={industryLoading}
<option key={indu.id} value={indu.id}> className="shadow-none border py-1 px-2 small"
{indu.name} required
</option> />
))
)} )}
</select> />
{errors.industryId && ( {errors.industryId && (
<div className="danger-text">{errors.industryId.message}</div> <div className="danger-text">{errors.industryId.message}</div>
)} )}
</div> </div>
<div className="col-sm-6"> <div className="col-sm-6 mb-2 mb-md-4 mt-n3">
<Label htmlFor="reference" required>Reference</Label> <AppFormController
<select name="reference"
id="reference" control={control}
className="form-select shadow-none border py-1 px-2 small" render={({ field }) => (
{...register("reference")} <SelectField
> label="Reference"
{reference.map((org) => ( placeholder="Select Reference"
<option key={org.val} value={org.val}> options={reference ?? []}
{org.name} labelKey="name"
</option> valueKey="val"
))} value={field.value}
</select> onChange={field.onChange}
className="shadow-none border py-1 px-2 small m-0"
required
/>
)}
/>
{errors.reference && ( {errors.reference && (
<div className="danger-text">{errors.reference.message}</div> <small className="danger-text">{errors.reference.message}</small>
)} )}
</div> </div>
<div className="col-sm-6">
<div className="col-sm-6 mt-n3">
<SelectMultiple <SelectMultiple
name="serviceIds" name="serviceIds"
label="Services" label="Services"
@ -229,7 +240,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
<textarea <textarea
id="description" id="description"
rows={3} rows={3}
className={`form-control form-control-sm `} className={`form-control `}
{...register("description")} {...register("description")}
/> />
{errors.description && ( {errors.description && (

View File

@ -43,6 +43,7 @@ const TenantForm = () => {
const tenantForm = useForm({ const tenantForm = useForm({
resolver: zodResolver(newTenantSchema), resolver: zodResolver(newTenantSchema),
defaultValues: tenantDefaultValues, defaultValues: tenantDefaultValues,
mode: "onChange",
}); });
const subscriptionForm = useForm({ const subscriptionForm = useForm({

View File

@ -114,9 +114,8 @@ const TenantsList = ({
align: "text-center", align: "text-center",
getValue: (t) => ( getValue: (t) => (
<span <span
className={`badge ${ className={`badge ${getTenantStatus(t.tenantStatus?.id) || "secondary"
getTenantStatus(t.tenantStatus?.id) || "secondary" }`}
}`}
> >
{t.tenantStatus?.name || "Unknown"} {t.tenantStatus?.name || "Unknown"}
</span> </span>
@ -151,13 +150,12 @@ const TenantsList = ({
<tbody> <tbody>
{data?.data.length > 0 ? ( {data?.data.length > 0 ? (
data.data.map((tenant) => ( data.data.map((tenant) => (
<tr key={tenant.id}> <tr key={tenant.id} style={{ height: "50px" }}>
{TenantColumns.map((col) => ( {TenantColumns.map((col) => (
<td <td
key={col.key} key={col.key}
className={`d-table-cell px-3 py-2 align-middle ${ className={`d-table-cell px-3 py-2 align-middle ${col.align ?? ""
col.align ?? "" }`}
}`}
> >
{col.customRender {col.customRender
? col.customRender(tenant) ? col.customRender(tenant)

View File

@ -219,7 +219,7 @@ const ManageCollection = ({ collectionId, onClose }) => {
</div> </div>
<div className="col-12 col-md-6 mb-2"> <div className="col-12 col-md-6 mb-4">
<Label required>Title</Label> <Label required>Title</Label>
<input <input
type="text" type="text"
@ -230,7 +230,7 @@ const ManageCollection = ({ collectionId, onClose }) => {
<small className="danger-text">{errors.title.message}</small> <small className="danger-text">{errors.title.message}</small>
)} )}
</div> </div>
<div className="col-12 col-md-6 mb-2"> <div className="col-12 col-md-6 mb-2">
<Label required>Invoice Number</Label> <Label required>Invoice Number</Label>
<input <input
type="text" type="text"
@ -256,7 +256,7 @@ const ManageCollection = ({ collectionId, onClose }) => {
</small> </small>
)} )}
</div> </div>
<div className="col-12 col-md-6 mb-2"> <div className="col-12 col-md-6 mb-4">
<Label required>Invoice Date</Label> <Label required>Invoice Date</Label>
<DatePicker <DatePicker
className="w-100" className="w-100"
@ -271,7 +271,7 @@ const ManageCollection = ({ collectionId, onClose }) => {
</small> </small>
)} )}
</div> </div>
<div className="col-12 col-md-6 mb-2"> <div className="col-12 col-md-6 mb-4">
<Label required>Expected Payment Date</Label> <Label required>Expected Payment Date</Label>
<DatePicker <DatePicker
className="w-100" className="w-100"
@ -286,7 +286,7 @@ const ManageCollection = ({ collectionId, onClose }) => {
</small> </small>
)} )}
</div> </div>
<div className="col-12 col-md-6 mb-2"> <div className="col-12 col-md-6 mb-2">
<Label required>Submission Date (Client)</Label> <Label required>Submission Date (Client)</Label>
<DatePicker <DatePicker
className="w-100" className="w-100"
@ -340,7 +340,7 @@ const ManageCollection = ({ collectionId, onClose }) => {
</small> </small>
)} )}
</div> </div>
<div className="col-12 my-2 text-start mb-2"> <div className="col-12 my-2 text-start mb-2">
<div className="col-md-12"> <div className="col-md-12">
<Label htmlFor="description" className="form-label" required> <Label htmlFor="description" className="form-label" required>
Description Description
@ -359,7 +359,7 @@ const ManageCollection = ({ collectionId, onClose }) => {
</div> </div>
</div> </div>
<div className="col-12"> <div className="col-12 my-3">
<Label className="form-label" required> <Label className="form-label" required>
Upload Bill{" "} Upload Bill{" "}
</Label> </Label>

View File

@ -228,7 +228,7 @@ const CreateRole = ({ modalType, onClose }) => {
</div> </div>
{masterFeatures && ( {masterFeatures && (
<div className="col-12 text-end"> <div className="col-12 text-end mt-5">
<button <button
type="reset" type="reset"
className="btn btn-sm btn-label-secondary me-3" className="btn btn-sm btn-label-secondary me-3"

View File

@ -90,7 +90,7 @@ const CreateWorkCategory = ({ onClose }) => {
/> />
{errors.name && <p className="text-danger">{errors.name.message}</p>} {errors.name && <p className="text-danger">{errors.name.message}</p>}
</div> </div>
<div className="col-12 col-md-12 text-start"> <div className="col-12 col-md-12 text-start my-3">
<Label className="form-label" htmlFor="description" required>Description</Label> <Label className="form-label" htmlFor="description" required>Description</Label>
<textarea <textarea
rows="3" rows="3"

View File

@ -276,7 +276,7 @@ const EditMaster = ({ master, onClose }) => {
<div className="col-12 text-end mt-3"> <div className="col-12 text-end mt-5">
<button <button
type="button" type="button"
className="btn btn-sm btn-label-secondary me-3" className="btn btn-sm btn-label-secondary me-3"

View File

@ -9,6 +9,8 @@ import {
useUpdateDocumentCategory, useUpdateDocumentCategory,
} from "../../hooks/masterHook/useMaster"; } from "../../hooks/masterHook/useMaster";
import Label from "../common/Label"; import Label from "../common/Label";
import { AppFormController } from "../../hooks/appHooks/useAppForm";
import SelectField from "../common/Forms/SelectField";
export const Document_Entity = Object.entries(DOCUMENTS_ENTITIES).map( export const Document_Entity = Object.entries(DOCUMENTS_ENTITIES).map(
([key, value]) => ({ key, value }) ([key, value]) => ({ key, value })
@ -34,6 +36,7 @@ const ManageDocumentCategory = ({ data, onClose }) => {
register, register,
handleSubmit, handleSubmit,
reset, reset,
control,
formState: { errors }, formState: { errors },
} = methods; } = methods;
@ -89,7 +92,7 @@ const ManageDocumentCategory = ({ data, onClose }) => {
<input <input
type="text" type="text"
{...register("name")} {...register("name")}
className={`form-control form-control-sm `} className={`form-control `}
/> />
{errors.name && ( {errors.name && (
<p className="danger-text">{errors.name.message}</p> <p className="danger-text">{errors.name.message}</p>
@ -97,36 +100,43 @@ const ManageDocumentCategory = ({ data, onClose }) => {
</div> </div>
<div className="col-12"> <div className="col-12">
<Label required >Select Entity</Label> <AppFormController
<select name="entityTypeId"
className="form-select form-select-sm" control={control}
{...register("entityTypeId")} render={({ field }) => (
> <SelectField
<option value="" disabled>Select entity</option> label="Select Entity"
{Document_Entity.map((entity) => ( options={Document_Entity ?? []}
<option key={entity.key} value={entity.value}> placeholder="Select entity"
{entity.key} required
</option> labelKey="key"
))} valueKey="value"
</select> value={field.value}
onChange={field.onChange}
className="m-0 w-100"
/>
)}
/>
{errors.entityTypeId && ( {errors.entityTypeId && (
<p className="danger-text">{errors.entityTypeId.message}</p> <p className="danger-text">{errors.entityTypeId.message}</p>
)} )}
</div> </div>
<div className="col-12">
<div className="col-12 my-3">
<Label required >Description</Label> <Label required >Description</Label>
<textarea <textarea
rows="3" rows="3"
{...register("description")} {...register("description")}
className={`form-control form-control-sm`} className={`form-control `}
/> />
{errors.description && ( {errors.description && (
<p className="danger-text">{errors.description.message}</p> <p className="danger-text">{errors.description.message}</p>
)} )}
</div> </div>
<div className="d-flex flex-row justify-content-end gap-3 "> <div className="d-flex flex-row justify-content-end gap-3">
<button <button
type="button" type="button"
className="btn btn-sm btn-label-secondary" className="btn btn-sm btn-label-secondary"
@ -137,16 +147,16 @@ const ManageDocumentCategory = ({ data, onClose }) => {
</button> </button>
<button <button
type="submit" type="submit"
className="btn btn-sm btn-primary me-3" className="btn btn-sm btn-primary"
disabled={isPending || Updating} disabled={isPending || Updating}
> >
{isPending || Updating {isPending || Updating
? "Please Wait..." ? "Please Wait..."
: data : data
? "Update" ? "Update"
: "Submit"} : "Submit"}
</button> </button>
</div> </div>
</form> </form>
</div> </div>

View File

@ -5,6 +5,8 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useCreateDocumentType, useDocumentCategories, useUpdateDocumentType } from "../../hooks/masterHook/useMaster"; import { useCreateDocumentType, useDocumentCategories, useUpdateDocumentType } from "../../hooks/masterHook/useMaster";
import { DOCUMENTS_ENTITIES } from "../../utils/constants"; import { DOCUMENTS_ENTITIES } from "../../utils/constants";
import Label from "../common/Label"; import Label from "../common/Label";
import { AppFormController } from "../../hooks/appHooks/useAppForm";
import SelectField from "../common/Forms/SelectField";
export const Document_Entity = Object.entries(DOCUMENTS_ENTITIES).map( export const Document_Entity = Object.entries(DOCUMENTS_ENTITIES).map(
@ -33,21 +35,22 @@ const ManageDocumentType = ({ data, onClose, documentCategories = [] }) => {
isValidationRequired: true, isValidationRequired: true,
isMandatory: true, isMandatory: true,
documentCategoryId: "", documentCategoryId: "",
entityTypeId:"" entityTypeId: ""
}, },
}); });
const { const {
register, register,
handleSubmit, handleSubmit,
reset,watch, reset, watch,
control,
formState: { errors }, formState: { errors },
} = methods; } = methods;
const selectedDocumentEntity = watch("entityTypeId") const selectedDocumentEntity = watch("entityTypeId")
const {DocumentCategories,isLoading} = useDocumentCategories(selectedDocumentEntity) const { DocumentCategories, isLoading } = useDocumentCategories(selectedDocumentEntity)
const { mutate: createDocType, isPending: creating } = useCreateDocumentType(() => const { mutate: createDocType, isPending: creating } = useCreateDocumentType(() =>
onClose?.() onClose?.()
@ -55,15 +58,15 @@ const ManageDocumentType = ({ data, onClose, documentCategories = [] }) => {
const { mutate: updateDocType, isPending: updating } = useUpdateDocumentType(() => const { mutate: updateDocType, isPending: updating } = useUpdateDocumentType(() =>
onClose?.() onClose?.()
); );
const onSubmit = (payload) => { const onSubmit = (payload) => {
const { entityTypeId, ...rest } = payload; const { entityTypeId, ...rest } = payload;
if (data) { if (data) {
updateDocType({ id: data.id, payload: { ...rest, id: data.id } }); updateDocType({ id: data.id, payload: { ...rest, id: data.id } });
} else { } else {
createDocType(rest); createDocType(rest);
} }
}; };
useEffect(() => { useEffect(() => {
@ -76,7 +79,7 @@ const onSubmit = (payload) => {
isValidationRequired: data.isValidationRequired ?? true, isValidationRequired: data.isValidationRequired ?? true,
isMandatory: data.isMandatory ?? true, isMandatory: data.isMandatory ?? true,
documentCategoryId: data.documentCategory?.id ?? "", documentCategoryId: data.documentCategory?.id ?? "",
entityTypeId:data.documentCategory?.entityTypeId ?? "" entityTypeId: data.documentCategory?.entityTypeId ?? ""
}); });
} }
}, [data]); }, [data]);
@ -96,7 +99,7 @@ const onSubmit = (payload) => {
<input <input
type="text" type="text"
{...register("name")} {...register("name")}
className={`form-control form-control-sm `} className={`form-control `}
/> />
{errors.name && <a className="text-danger">{errors.name.message}</a>} {errors.name && <a className="text-danger">{errors.name.message}</a>}
</div> </div>
@ -107,7 +110,7 @@ const onSubmit = (payload) => {
<input <input
type="text" type="text"
{...register("regexExpression")} {...register("regexExpression")}
className="form-control form-control-sm" className="form-control "
/> />
</div> </div>
@ -117,7 +120,7 @@ const onSubmit = (payload) => {
<input <input
type="text" type="text"
{...register("allowedContentType")} {...register("allowedContentType")}
className={`form-control form-control form-control-sm`} className={`form-control form-control `}
/> />
{errors.allowedContentType && ( {errors.allowedContentType && (
<a className="text-danger">{errors.allowedContentType.message}</a> <a className="text-danger">{errors.allowedContentType.message}</a>
@ -130,7 +133,7 @@ const onSubmit = (payload) => {
<input <input
type="number" type="number"
{...register("maxSizeAllowedInMB", { valueAsNumber: true })} {...register("maxSizeAllowedInMB", { valueAsNumber: true })}
className={`form-control form-control-sm`} className={`form-control `}
/> />
{errors.maxSizeAllowedInMB && ( {errors.maxSizeAllowedInMB && (
<a className="text-danger">{errors.maxSizeAllowedInMB.message}</a> <a className="text-danger">{errors.maxSizeAllowedInMB.message}</a>
@ -156,47 +159,59 @@ const onSubmit = (payload) => {
/> />
<label className="form-check-label">Mandatory</label> <label className="form-check-label">Mandatory</label>
</div> </div>
<div className="col-12"> {/* Document Entity */}
<label className="form-label">Document Entity</label>
<select
{...register("entityTypeId")}
className={`form-select form-select-sm`}
>
<option value="">-- Select Category --</option>
{Document_Entity.map((entity) => (
<option key={entity.key} value={entity.value}>
{entity.key}
</option>
))}
</select>
{errors.entityTypeId && (
<a className="text-danger">{errors.entityTypeId.message}</a>
)}
</div>
{/* Category */}
<div className="col-12"> <div className="col-12">
<Label required> Document Category</Label> <AppFormController
<select name="entityTypeId"
{...register("documentCategoryId")} control={control}
className={`form-select form-select-sm`} render={({ field }) => (
> <SelectField
label="Document Entity"
{isLoading && <option value="" disabled>Loading....</option> } options={Document_Entity ?? []}
<option value="">-- Select Category --</option> placeholder="-- Select Category --"
{!isLoading && DocumentCategories?.map((cat) => ( required
<option key={cat.id} value={cat.id}> labelKey="key"
{cat.name} valueKey="value"
</option> value={field.value}
))} onChange={field.onChange}
</select> className="m-0 w-100"
{errors.documentCategoryId && ( />
<a className="text-danger">{errors.documentCategoryId.message}</a> )}
/>
{errors.entityTypeId && (
<small className="text-danger">{errors.entityTypeId.message}</small>
)} )}
</div> </div>
{/* Document Category */}
<div className="col-12 my-3">
<AppFormController
name="documentCategoryId"
control={control}
render={({ field }) => (
<SelectField
label="Document Category"
options={DocumentCategories ?? []}
placeholder={isLoading ? "Loading..." : "-- Select Category --"}
required
labelKey="name"
valueKey="id"
value={field.value}
onChange={field.onChange}
isLoading={isLoading}
className="m-0 w-100"
/>
)}
/>
{errors.documentCategoryId && (
<small className="text-danger">{errors.documentCategoryId.message}</small>
)}
</div>
{/* Buttons */} {/* Buttons */}
<div className="d-flex flex-row justify-content-end gap-3 "> <div className="d-flex flex-row justify-content-end gap-3 ">
<button <button
type="button" type="button"
className="btn btn-sm btn-label-secondary" className="btn btn-sm btn-label-secondary"
onClick={onClose} onClick={onClose}
@ -212,10 +227,10 @@ const onSubmit = (payload) => {
{creating || updating {creating || updating
? "Please Wait..." ? "Please Wait..."
: data : data
? "Update" ? "Update"
: "Submit"} : "Submit"}
</button> </button>
</div> </div>
</form> </form>
</FormProvider> </FormProvider>

View File

@ -56,7 +56,7 @@ const ManagePaymentMode = ({ data = null, onClose }) => {
/> />
{errors.name && <p className="danger-text">{errors.name.message}</p>} {errors.name && <p className="danger-text">{errors.name.message}</p>}
</div> </div>
<div className="col-12 col-md-12 text-start"> <div className="col-12 col-md-12 text-start my-3">
<Label className="form-label" htmlFor="description" required> <Label className="form-label" htmlFor="description" required>
Description Description
</Label> </Label>

View File

@ -145,7 +145,7 @@ const ManageActivity = ({ activity = null, whichGroup = null, close }) => {
<input <input
type="text" type="text"
{...register("activityName")} {...register("activityName")}
className={`form-control form-control-sm ${ className={`form-control ${
errors.activityName ? "is-invalid" : "" errors.activityName ? "is-invalid" : ""
}`} }`}
/> />
@ -161,7 +161,7 @@ const ManageActivity = ({ activity = null, whichGroup = null, close }) => {
<input <input
type="text" type="text"
{...register("unitOfMeasurement")} {...register("unitOfMeasurement")}
className={`form-control form-control-sm ${ className={`form-control ${
errors.unitOfMeasurement ? "is-invalid" : "" errors.unitOfMeasurement ? "is-invalid" : ""
}`} }`}
/> />
@ -203,7 +203,7 @@ const ManageActivity = ({ activity = null, whichGroup = null, close }) => {
></input> ></input>
<input <input
{...register(`checkList.${index}.description`)} {...register(`checkList.${index}.description`)}
className="form-control form-control-sm" className="form-control "
placeholder={`Checklist item ${index + 1}`} placeholder={`Checklist item ${index + 1}`}
onChange={(e) => onChange={(e) =>
handleChecklistChange(index, e.target.value) handleChecklistChange(index, e.target.value)

View File

@ -62,7 +62,7 @@ const ManageGroup = ({ group = null, whichService = null, close }) => {
<input <input
type="text" type="text"
{...register("name")} {...register("name")}
className={`form-control form-control-sm ${errors.name ? "is-invalids" : "" className={`form-control ${errors.name ? "is-invalids" : ""
}`} }`}
/> />
{errors.name && ( {errors.name && (
@ -76,7 +76,7 @@ const ManageGroup = ({ group = null, whichService = null, close }) => {
<textarea <textarea
rows="3" rows="3"
{...register("description")} {...register("description")}
className={`form-control form-control-sm ${errors.description ? "is-invalids" : "" className={`form-control ${errors.description ? "is-invalids" : ""
}`} }`}
></textarea> ></textarea>

View File

@ -62,7 +62,7 @@ const ManageServices = ({ data , onClose }) => {
{errors.name && <p className="danger-text">{errors.name.message}</p>} {errors.name && <p className="danger-text">{errors.name.message}</p>}
</div> </div>
<div className="col-12 col-md-12 text-start"> <div className="col-12 col-md-12 text-start my-3">
<Label className="form-label" htmlFor="description" required> <Label className="form-label" htmlFor="description" required>
Description Description
</Label> </Label>

View File

@ -40,7 +40,7 @@ const ServiceGroups = ({ service }) => {
<div className="accordion" id="accordionExample"> <div className="accordion" id="accordionExample">
<div className="accordion-item active shadow-none"> <div className="accordion-item active shadow-none">
{/* Service Header */} {/* Service Header */}
<div className="d-flex justify-content-between text-start align-items-center accordion-header py-1"> <div className="d-flex justify-content-between text-start align-items-center accordion-header py-3">
<p className="m-0 fw-bold fs-6">{service.name}</p> <p className="m-0 fw-bold fs-6">{service.name}</p>
<button <button
className="btn btn-sm btn-primary" className="btn btn-sm btn-primary"

View File

@ -75,7 +75,7 @@ const ManagePaymentHead = ({ data, onClose }) => {
)} )}
</div> </div>
<div className="mb-3"> <div className="my-3">
<Label htmlFor="description" required> <Label htmlFor="description" required>
Description Description
</Label> </Label>

View File

@ -142,7 +142,7 @@ const DeliveryChallane = ({ purchaseId }) => {
label="Select Document Type" label="Select Document Type"
options={data ?? []} options={data ?? []}
placeholder="Choose Type" placeholder="Choose Type"
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}

View File

@ -111,7 +111,7 @@ const PurchasePayment = ({ onClose, purchaseId }) => {
options={paymentTypes?.data ?? []} options={paymentTypes?.data ?? []}
placeholder="Choose a Status" placeholder="Choose a Status"
required required
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}

View File

@ -223,7 +223,7 @@ const PurchasePaymentDetails = ({ purchaseId = null }) => {
label="Select Document Type" label="Select Document Type"
options={InvoiceDocTypes ?? []} options={InvoiceDocTypes ?? []}
placeholder="Choose Type" placeholder="Choose Type"
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKeyKey="id"
value={field.value} value={field.value}
onChange={field.onChange} onChange={field.onChange}

View File

@ -16,10 +16,10 @@ const TaskPlanning = () => {
const selectedService = useCurrentService(); const selectedService = useCurrentService();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { control } = useForm({ const { control } = useForm({
defaultValues: { defaultValues: {
serviceFilter: selectedService ?? "" serviceFilter: selectedService ?? ""
}, },
}); });
const { projectNames = [], loading: projectLoading } = useProjectName(); const { projectNames = [], loading: projectLoading } = useProjectName();
@ -60,14 +60,14 @@ const TaskPlanning = () => {
<SelectField <SelectField
label="Services" label="Services"
placeholder="All Services" placeholder="All Services"
options={data ?? []} options={[{ id: "", name: "All Services" }, ...(data ?? [])]}
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKey="id"
isLoading={servicesLoading} isLoading={servicesLoading}
value={field.value} value={field.value}
onChange={(val) => { onChange={(val) => {
field.onChange(val); // react-hook-form update field.onChange(val);
dispatch(setService(val)); // Redux update dispatch(setService(val));
}} }}
className="m-0" className="m-0"
/> />
@ -77,6 +77,7 @@ const TaskPlanning = () => {
</div> </div>
{/* Planning Component */} {/* Planning Component */}
{selectedProject ? ( {selectedProject ? (
<InfraPlanning /> <InfraPlanning />

View File

@ -107,15 +107,15 @@ const DailyProgrssReport = () => {
render={({ field }) => ( render={({ field }) => (
<SelectField <SelectField
label="Services" label="Services"
options={data ?? []} options={[{ id: "", name: "All Projects" }, ...(data ?? [])]}
placeholder="All Services" placeholder="Select Service"
labelKeyKey="name" labelKey="name"
valueKeyKey="id" valueKey="id"
isLoading={isLoading} isLoading={isLoading}
value={field.value} value={field.value}
onChange={(val) => { onChange={(val) => {
field.onChange(val); // update RHF field.onChange(val);
setService(val); // update your local filter state setService(val);
}} }}
className="m-0" className="m-0"
/> />
@ -129,6 +129,7 @@ const DailyProgrssReport = () => {
</div> </div>
</div> </div>
</DailyProgrssContext.Provider> </DailyProgrssContext.Provider>
</div> </div>
); );

View File

@ -71,8 +71,7 @@ const ChangePasswordPage = () => {
const bodyContxt = ( const bodyContxt = (
<div className="row"> <div className="row">
<h5 className="mb-2">Change Password</h5> <h5 className="mb-2">Change Password</h5>
<p className="mb-4 text-black"> <p className="mb-4 text-black">
@ -86,7 +85,7 @@ const ChangePasswordPage = () => {
<div className="input-group input-group-merge d-flex align-items-center border rounded px-2"> <div className="input-group input-group-merge d-flex align-items-center border rounded px-2">
<input <input
type={hideOldPass ? "password" : "text"} type={hideOldPass ? "password" : "text"}
className="form-control form-control-sm border-0 shadow-none" className="form-control border-0 shadow-none"
{...register("oldPassword")} {...register("oldPassword")}
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;" placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
style={{ flex: 1 }} style={{ flex: 1 }}
@ -112,7 +111,7 @@ const ChangePasswordPage = () => {
<div className="input-group input-group-merge d-flex align-items-center border rounded px-2"> <div className="input-group input-group-merge d-flex align-items-center border rounded px-2">
<input <input
type={hideNewPass ? "password" : "text"} type={hideNewPass ? "password" : "text"}
className="form-control form-control-sm border-0 shadow-none" className="form-control border-0 shadow-none"
{...register("newPassword")} {...register("newPassword")}
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;" placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
style={{ flex: 1 }} style={{ flex: 1 }}
@ -142,7 +141,7 @@ const ChangePasswordPage = () => {
<div className="input-group input-group-merge d-flex align-items-center border rounded px-2"> <div className="input-group input-group-merge d-flex align-items-center border rounded px-2">
<input <input
type={hideConfirmPass ? "password" : "text"} type={hideConfirmPass ? "password" : "text"}
className="form-control form-control-sm border-0 shadow-none" className="form-control border-0 shadow-none"
{...register("confirmPassword")} {...register("confirmPassword")}
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;" placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
style={{ flex: 1 }} style={{ flex: 1 }}
@ -168,28 +167,28 @@ const ChangePasswordPage = () => {
)} )}
</div> </div>
<div className="d-flex justify-content-center pt-2 text-muted small text-black"> <div className="d-flex justify-content-center my-5 text-muted small text-black">
Your password must have at least 8 characters and include a lower Your password must have at least 8 characters and include a lower
case letter, an uppercase letter, a number, and a special case letter, an uppercase letter, a number, and a special
character. character.
</div> </div>
{/* Action Buttons */} {/* Action Buttons */}
<div className="d-flex justify-content-center pt-4"> <div className="d-flex justify-content-end">
<button
type="submit"
className="btn btn-primary btn-sm me-2"
disabled={loading}
>
{loading ? "Please Wait..." : "Change Password"}
</button>
<button <button
type="button" type="button"
className="btn btn-outline-secondary btn-sm" className="btn btn-outline-secondary btn-sm me-2"
onClick={onClose} onClick={onClose}
disabled={loading} disabled={loading}
> >
Cancel Cancel
</button> </button>
<button
type="submit"
className="btn btn-primary btn-sm"
disabled={loading}
>
{loading ? "Please Wait..." : "Change Password"}
</button>
</div> </div>
</form> </form>
</div> </div>

View File

@ -15,6 +15,9 @@ import { changeMaster } from "../../slices/localVariablesSlice";
import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { MANAGE_MASTER } from "../../utils/constants"; import { MANAGE_MASTER } from "../../utils/constants";
import GlobalModel from "../../components/common/GlobalModel"; import GlobalModel from "../../components/common/GlobalModel";
import { AppFormController } from "../../hooks/appHooks/useAppForm";
import SelectField from "../../components/common/Forms/SelectField";
import { useForm } from "react-hook-form";
export const MasterContext = createContext(); export const MasterContext = createContext();
@ -33,6 +36,11 @@ const MasterPage = () => {
(store) => store.localVariables.selectedMaster (store) => store.localVariables.selectedMaster
); );
const hasMasterPermission = useHasUserPermission(MANAGE_MASTER); const hasMasterPermission = useHasUserPermission(MANAGE_MASTER);
const { control, handleSubmit } = useForm({
defaultValues: {
masterSelection: selectedMaster || "",
},
});
const { const {
data: menuData, data: menuData,
@ -46,9 +54,9 @@ const MasterPage = () => {
isError: isMasterError, isError: isMasterError,
} = useMaster(); } = useMaster();
const { mutate: DeleteMaster, isPending: isDeleting } = useDeleteMasterItem(); const { mutate: DeleteMaster, isPending: isDeleting } = useDeleteMasterItem();
const [isDeleletingServiceItem,setDeleletingServiceItem] = useState({isOpen:false,ItemId:null,whichItem:null}) const [isDeleletingServiceItem, setDeleletingServiceItem] = useState({ isOpen: false, ItemId: null, whichItem: null })
const {mutate:DeleteSericeGroup,isPending:deletingGroup} =useDeleteServiceGroup() const { mutate: DeleteSericeGroup, isPending: deletingGroup } = useDeleteServiceGroup()
const {mutate:DeleteAcivity,isPending:deletingActivity} = useDeleteActivity() const { mutate: DeleteAcivity, isPending: deletingActivity } = useDeleteActivity()
const [modalConfig, setModalConfig] = useState(null); const [modalConfig, setModalConfig] = useState(null);
const [deleteData, setDeleteData] = useState(null); const [deleteData, setDeleteData] = useState(null);
@ -89,15 +97,15 @@ const MasterPage = () => {
}; };
const handleDeleteServiceItem =()=>{ const handleDeleteServiceItem = () => {
if(!isDeleletingServiceItem.ItemId) return if (!isDeleletingServiceItem.ItemId) return
debugger debugger
if(isDeleletingServiceItem.whichItem === "activity"){ if (isDeleletingServiceItem.whichItem === "activity") {
DeleteAcivity(isDeleletingServiceItem.ItemId,{onSuccess:()=>setDeleletingServiceItem({isOpen:false,ItemId:null,whichItem:null})}) DeleteAcivity(isDeleletingServiceItem.ItemId, { onSuccess: () => setDeleletingServiceItem({ isOpen: false, ItemId: null, whichItem: null }) })
}else{ } else {
DeleteSericeGroup(isDeleletingServiceItem.ItemId,{onSuccess:()=>setDeleletingServiceItem({isOpen:false,ItemId:null,whichItem:null})}) DeleteSericeGroup(isDeleletingServiceItem.ItemId, { onSuccess: () => setDeleletingServiceItem({ isOpen: false, ItemId: null, whichItem: null }) })
} }
} }
@ -115,7 +123,7 @@ const MasterPage = () => {
); );
return ( return (
<MasterContext.Provider value={{setDeleletingServiceItem}}> <MasterContext.Provider value={{ setDeleletingServiceItem }}>
{modalConfig && ( {modalConfig && (
<GlobalModel <GlobalModel
size={ size={
@ -134,8 +142,6 @@ const MasterPage = () => {
/> />
</GlobalModel> </GlobalModel>
)} )}
<ConfirmModal <ConfirmModal
type="delete" type="delete"
header={`Delete ${selectedMaster}`} header={`Delete ${selectedMaster}`}
@ -145,15 +151,15 @@ const MasterPage = () => {
onSubmit={handleDeleteSubmit} onSubmit={handleDeleteSubmit}
onClose={() => setDeleteData(null)} onClose={() => setDeleteData(null)}
/> />
<ConfirmModal <ConfirmModal
type="delete" type="delete"
header={`Delete ${isDeleletingServiceItem?.whichItem}`} header={`Delete ${isDeleletingServiceItem?.whichItem}`}
message={`Are you sure you want to delete this ${isDeleletingServiceItem?.whichItem}?`} message={`Are you sure you want to delete this ${isDeleletingServiceItem?.whichItem}?`}
isOpen={!!isDeleletingServiceItem?.isOpen} isOpen={!!isDeleletingServiceItem?.isOpen}
loading={deletingActivity} loading={deletingActivity}
onSubmit={handleDeleteServiceItem} onSubmit={handleDeleteServiceItem}
onClose={() => setDeleletingServiceItem({isOpen:false,ItemId:null,whichItem:null})} onClose={() => setDeleletingServiceItem({ isOpen: false, ItemId: null, whichItem: null })}
/> />
<div className="container-fluid"> <div className="container-fluid">
@ -164,28 +170,34 @@ const MasterPage = () => {
<div className="row page-min-h"> <div className="row page-min-h">
<div className="card"> <div className="card">
<div <div
className="card-datatable table-responsive py-2 py-md-10 mx-1 mx-md-5 " className="card-datatable table-responsive py-2 py-md-6 mx-1 mx-md-5 "
style={{ overflow: "hidden" }} style={{ overflow: "hidden" }}
> >
<div className="row mb-2"> <div className="row mb-2">
<div className="col-12 col-md-3"> <div className="col-12 col-md-3 text-start">
<select <AppFormController
className="form-select py-1 px-2" name="masterSelection"
control={control}
value={selectedMaster} render={({ field }) => (
onChange={(e) => dispatch(changeMaster(e.target.value))} <SelectField
> label="Select Master"
{menuLoading ? ( options={menuData ?? []}
<option value="">Loading...</option> placeholder={menuLoading ? "Loading..." : "Choose Master"}
) : ( required
menuData?.map((item) => ( labelKey="name"
<option key={item.id} value={item.name}> valueKey="name"
{item.name} value={field.value}
</option> onChange={(val) => {
)) field.onChange(val); // update form value
dispatch(changeMaster(val)); // update Redux state
}}
isLoading={menuLoading}
className="m-0 w-100 py-1 px-2"
/>
)} )}
</select> />
</div> </div>
<div className="col-12 col-md-9 d-flex justify-content-between justify-content-md-end align-items-center gap-2 mt-2 mt-md-0"> <div className="col-12 col-md-9 d-flex justify-content-between justify-content-md-end align-items-center gap-2 mt-2 mt-md-0">
<div className="col-8 col-md-3"> <div className="col-8 col-md-3">
<input <input
@ -204,7 +216,7 @@ const MasterPage = () => {
} }
> >
<i className="bx bx-plus-circle me-2"></i> <span className="d-none d-md-inline-block">Add{" "} <i className="bx bx-plus-circle me-2"></i> <span className="d-none d-md-inline-block">Add{" "}
{selectedMaster}</span> {selectedMaster}</span>
</button> </button>
)} )}
</div> </div>
@ -220,7 +232,7 @@ const MasterPage = () => {
</div> </div>
</div> </div>
</div> </div>
</MasterContext.Provider> </MasterContext.Provider>
); );
}; };

View File

@ -80,7 +80,7 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
}; };
return ( return (
<div className="table-responsive"> <div className="table-responsive mt-5">
{loading ? ( {loading ? (
<p>Loading...</p> <p>Loading...</p>
) : ( ) : (
@ -92,14 +92,14 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
{" "} {" "}
{selectedMaster === "Activity" ? "Activity" : "Name"} {selectedMaster === "Activity" ? "Activity" : "Name"}
</th> </th>
<th className="text-start d-none d-md-table-cell"> <th className="text-start d-none d-md-table-cell">
{" "} {" "}
{selectedMaster === "Activity" {selectedMaster === "Activity"
? "Unit" ? "Unit"
: selectedMaster === "Document Type" : selectedMaster === "Document Type"
? "Content Type" ? "Content Type"
: "Description"} : "Description"}
</th> </th>
<th className={` ${!hasMasterPermission && "d-none"}`}> <th className={` ${!hasMasterPermission && "d-none"}`}>
Actions Actions
@ -109,15 +109,15 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
<tbody> <tbody>
{currentItems.length > 0 ? ( {currentItems.length > 0 ? (
currentItems.map((item, index) => ( currentItems.map((item, index) => (
<tr key={index} > <tr key={index} style={{ height: "40px" }}>
<td style={{ width: "20px" }} className="py-3"> <td className="py-3">
<i className="bx bx-right-arrow-alt"></i> <i className="bx bx-right-arrow-alt"></i>
</td> </td>
{updatedColumns.map((col) => ( {updatedColumns.map((col) => (
<td className={`text-start mx-2 py-3 ${col.key === "description" && "d-none d-md-table-cell"}`} key={col.key} > <td className={`text-start mx-2 py-3 ${col.key === "description" && "d-none d-md-table-cell"}`} key={col.key} >
{col.key === "description" ? ( {col.key === "description" ? (
item[col.key] !== undefined && item[col.key] !== undefined &&
item[col.key] !== null ? ( item[col.key] !== null ? (
item[col.key].length > 80 ? ( item[col.key].length > 80 ? (
<>{item[col.key].slice(0, 80)}...</> <>{item[col.key].slice(0, 80)}...</>
) : ( ) : (
@ -137,7 +137,7 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
<td className={!hasMasterPermission ? "d-none" : "py-3"}> <td className={!hasMasterPermission ? "d-none" : "py-3"}>
{(selectedMaster === "Application Role" || {(selectedMaster === "Application Role" ||
selectedMaster === "Work Category") && selectedMaster === "Work Category") &&
item?.isSystem ? ( item?.isSystem ? (
<> <>
<button <button
aria-label="Modify" aria-label="Modify"
@ -230,9 +230,8 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
{[...Array(totalPages)].map((_, index) => ( {[...Array(totalPages)].map((_, index) => (
<li <li
key={index} key={index}
className={`page-item ${ className={`page-item ${currentPage === index + 1 ? "active" : ""
currentPage === index + 1 ? "active" : "" }`}
}`}
> >
<button <button
className="page-link" className="page-link"
@ -243,9 +242,8 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
</li> </li>
))} ))}
<li <li
className={`page-item ${ className={`page-item ${currentPage === totalPages ? "disabled" : ""
currentPage === totalPages ? "disabled" : "" }`}
}`}
> >
<button <button
className="page-link" className="page-link"