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

@ -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

@ -4,6 +4,9 @@ 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,33 +161,37 @@ 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 && ( {assignedServices.length === 1 && (
<h5 className="mb-2">{assignedServices[0].name}</h5> <h5 className="mb-2">{assignedServices[0].name}</h5>
)} )}
{assignedServices?.length > 1 && ( {assignedServices.length > 1 && (
<select <div className="col-12 col-md-6 mb-2 text-start">
className="form-select form-select-sm" <AppFormController
aria-label="Select Service" name="selectedService"
value={selectedService} control={control}
onChange={handleServiceChange} render={({ field }) => (
> <SelectField
<option value="">All Services</option> label="Select Service"
{assignedServices.map((service) => ( options={[{ id: "", name: "All Services" }, ...assignedServices]}
<option key={service.id} value={service.id}> placeholder="Choose a Service"
{service.name} labelKey="name"
</option> valueKey="id"
))} value={field.value}
</select> onChange={field.onChange}
isLoading={servicesLoading}
className="w-100"
/>
)}
/>
</div>
)} )}
</> </>
)} )}
</div>
<div className="form-check form-switch d-flex align-items-center text-nowrap"> <div className="form-check form-switch d-flex align-items-center text-nowrap">
<input <input
@ -190,26 +201,28 @@ const Teams = () => {
checked={activeEmployee} checked={activeEmployee}
onChange={handleToggleActive} onChange={handleToggleActive}
/> />
<label <label className="form-check-label ms-2" htmlFor="activeEmployeeSwitch">
className="form-check-label ms-2"
htmlFor="activeEmployeeSwitch"
>
{activeEmployee ? "Active Employees" : "In-active Employees"} {activeEmployee ? "Active Employees" : "In-active Employees"}
</label> </label>
</div> </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">
<div className="col-12 col-md-4">
<AppFormController
name="searchTerm"
control={control}
render={({ field }) => (
<input <input
type="search" type="search"
className="form-control form-control-sm" className="form-control form-control-sm w-100"
placeholder="Search by Name or Role" placeholder="Search by Name or Role"
aria-controls="DataTables_Table_0" value={field.value}
style={{ maxWidth: "200px" }} onChange={field.onChange}
value={searchTerm}
onChange={handleSearch}
/> />
)}
/>
</div>
{HasAssignUserPermission && ( {HasAssignUserPermission && (
<button <button
@ -246,8 +259,7 @@ 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 || "")
) )

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,8 +114,7 @@ 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"}
@ -151,12 +150,11 @@ 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

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"
@ -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"
@ -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,29 +100,36 @@ 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>
@ -137,7 +147,7 @@ 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

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(
@ -40,6 +42,7 @@ const ManageDocumentType = ({ data, onClose, documentCategories = [] }) => {
register, register,
handleSubmit, handleSubmit,
reset, watch, reset, watch,
control,
formState: { errors }, formState: { errors },
} = methods; } = methods;
@ -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,44 +159,56 @@ const onSubmit = (payload) => {
/> />
<label className="form-check-label">Mandatory</label> <label className="form-check-label">Mandatory</label>
</div> </div>
{/* Document Entity */}
<div className="col-12"> <div className="col-12">
<label className="form-label">Document Entity</label> <AppFormController
<select name="entityTypeId"
{...register("entityTypeId")} control={control}
className={`form-select form-select-sm`} render={({ field }) => (
> <SelectField
<option value="">-- Select Category --</option> label="Document Entity"
{Document_Entity.map((entity) => ( options={Document_Entity ?? []}
<option key={entity.key} value={entity.value}> placeholder="-- Select Category --"
{entity.key} required
</option> labelKey="key"
))} valueKey="value"
</select> value={field.value}
onChange={field.onChange}
className="m-0 w-100"
/>
)}
/>
{errors.entityTypeId && ( {errors.entityTypeId && (
<a className="text-danger">{errors.entityTypeId.message}</a> <small className="text-danger">{errors.entityTypeId.message}</small>
)} )}
</div> </div>
{/* Category */}
<div className="col-12">
<Label required> Document Category</Label>
<select
{...register("documentCategoryId")}
className={`form-select form-select-sm`}
>
{isLoading && <option value="" disabled>Loading....</option> } {/* Document Category */}
<option value="">-- Select Category --</option> <div className="col-12 my-3">
{!isLoading && DocumentCategories?.map((cat) => ( <AppFormController
<option key={cat.id} value={cat.id}> name="documentCategoryId"
{cat.name} control={control}
</option> render={({ field }) => (
))} <SelectField
</select> 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 && ( {errors.documentCategoryId && (
<a className="text-danger">{errors.documentCategoryId.message}</a> <small className="text-danger">{errors.documentCategoryId.message}</small>
)} )}
</div> </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

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

@ -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

@ -73,7 +73,6 @@ const ChangePasswordPage = () => {
<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">
Enter old and new password to update. Enter old and new password to update.
@ -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,
@ -134,8 +142,6 @@ const MasterPage = () => {
/> />
</GlobalModel> </GlobalModel>
)} )}
<ConfirmModal <ConfirmModal
type="delete" type="delete"
header={`Delete ${selectedMaster}`} header={`Delete ${selectedMaster}`}
@ -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

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>
) : ( ) : (
@ -109,8 +109,8 @@ 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) => (
@ -230,8 +230,7 @@ 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
@ -243,8 +242,7 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
</li> </li>
))} ))}
<li <li
className={`page-item ${ className={`page-item ${currentPage === totalPages ? "disabled" : ""
currentPage === totalPages ? "disabled" : ""
}`} }`}
> >
<button <button