Change the UI of all components and add stars for all mandatory fields. #370

Merged
vikas.nale merged 10 commits from UI_Changes_PMS into Document_Manag 2025-09-08 06:30:58 +00:00
51 changed files with 1137 additions and 1037 deletions

View File

@ -114,7 +114,10 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
return (
<>
<div className="table-responsive text-nowrap h-100" >
<div
className="table-responsive text-nowrap h-100"
style={{ minHeight: "200px" }} // 🔹 Ensures fixed height
>
<div className="d-flex text-start align-items-center py-2">
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
<div className="form-check form-switch text-start m-0 ms-5">
@ -209,7 +212,11 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
</tr>
))}
{!attendance && (
<span className="text-secondary m-4">No employees assigned to the project!</span>
<tr>
<td colSpan={6} className="text-center text-secondary" style={{ height: "200px" }}>
No employees assigned to the project!
</td>
</tr>
)}
</tbody>
</table>
@ -258,7 +265,10 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
)}
</>
) : (
<div className="text-muted my-4">
<div
className="d-flex justify-content-center align-items-center text-muted"
style={{ height: "200px" }}
>
{searchTerm
? "No results found for your search."
: attendanceList.length === 0

View File

@ -42,7 +42,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [showPending,setShowPending] = useState(false)
const [showPending, setShowPending] = useState(false)
const [isRefreshing, setIsRefreshing] = useState(false);
const [processedData, setProcessedData] = useState([]);
@ -245,17 +245,16 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
</div>
<div className="col-md-2 m-0 text-end">
<i
className={`bx bx-refresh cursor-pointer fs-4 ${
isFetching ? "spin" : ""
}`}
className={`bx bx-refresh cursor-pointer fs-4 ${isFetching ? "spin" : ""
}`}
title="Refresh"
onClick={() => refetch()}
/>
</div>
</div>
<div className="table-responsive text-nowrap">
<div className="table-responsive text-nowrap" style={{ minHeight: "200px" }}>
{isLoading ? (
<div>
<div className="d-flex justify-content-center align-items-center" style={{ height: "200px" }}>
<p className="text-secondary">Loading...</p>
</div>
) : filteredSearchData?.length > 0 ? (
@ -284,9 +283,9 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
const previousAttendance = arr[index - 1];
const previousDate = previousAttendance
? moment(
previousAttendance.checkInTime ||
previousAttendance.checkOutTime
).format("YYYY-MM-DD")
previousAttendance.checkInTime ||
previousAttendance.checkOutTime
).format("YYYY-MM-DD")
: null;
if (!previousDate || currentDate !== previousDate) {
@ -346,12 +345,15 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
</tbody>
</table>
) : (
<div className="my-4"><span className="text-secondary">No Record Available !</span></div>
<div className="my-4"><span className="text-secondary">No Record Available !</span></div>
)}
</div>
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
<div className="my-4">
<span className="text-secondary">No Pending Record Available !</span>
<div
className="d-flex justify-content-center align-items-center text-secondary"
style={{ height: "200px" }}
>
No Record Available !
</div>
)}
{filteredSearchData.length > ITEMS_PER_PAGE && (
@ -369,9 +371,8 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
(pageNumber) => (
<li
key={pageNumber}
className={`page-item ${
currentPage === pageNumber ? "active" : ""
}`}
className={`page-item ${currentPage === pageNumber ? "active" : ""
}`}
>
<button
className="page-link"
@ -383,9 +384,8 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
)
)}
<li
className={`page-item ${
currentPage === totalPages ? "disabled" : ""
}`}
className={`page-item ${currentPage === totalPages ? "disabled" : ""
}`}
>
<button
className="page-link"

View File

@ -98,15 +98,16 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
return (
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
<label className="fs-5 text-dark text-center d-flex align-items-center flex-wrap">
<div className="col-12 d-flex justify-content-center">
<label className="fs-5 text-dark text-center">
{modeldata?.checkInTime && !modeldata?.checkOutTime
? "Check-out :"
: "Check-in :"}
</label>
</div>
<div className="col-6 col-md-6 ">
<div className="col-6 col-md-6 text-start">
<label className="form-label" htmlFor="checkInDate">
{modeldata?.checkInTime && !modeldata?.checkOutTime
? "Check-out Date"
@ -125,7 +126,7 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
/>
</div>
<div className="col-6 col-md-6">
<div className="col-6 col-md-6 text-start">
<TimePicker
label="Choose a time"
onChange={(e) => setValue("markTime", e)}
@ -138,7 +139,7 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
)}
</div>
<div className="col-12 col-md-12">
<div className="col-12 col-md-12 text-start">
<label className="form-label" htmlFor="description">
Description
</label>
@ -154,19 +155,19 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<div className="col-12 text-end mt-4">
<button
type="reset"
className="btn btn-sm btn-label-secondary"
className="btn btn-sm btn-label-secondary me-2"
data-bs-dismiss="modal"
aria-label="Close"
onClick={() => closeModal()}
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading ? "Please Wait..." : "Submit"}
</button>
</div>
</form>
);

View File

@ -87,9 +87,9 @@ const Regularization = ({ handleRequest, searchTerm }) => {
}, [employeeHandler]);
return (
<div className="table-responsive text-nowrap pb-4">
<div className="table-responsive text-nowrap pb-4" style={{ minHeight: "200px" }}>
{loading ? (
<div className="my-2">
<div className="d-flex justify-content-center align-items-center" style={{ height: "200px" }}>
<p className="text-secondary">Loading...</p>
</div>
) : currentItems?.length > 0 ? (
@ -143,9 +143,14 @@ const Regularization = ({ handleRequest, searchTerm }) => {
</tbody>
</table>
) : (
<div className="my-4">
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "200px" }}
>
<span className="text-secondary">
{searchTerm ? "No results found for your search." : "No Requests Found !"}
{searchTerm
? "No results found for your search."
: "No Requests Found !"}
</span>
</div>
)}
@ -163,9 +168,8 @@ const Regularization = ({ handleRequest, searchTerm }) => {
{[...Array(totalPages)].map((_, index) => (
<li
key={index}
className={`page-item ${
currentPage === index + 1 ? "active" : ""
}`}
className={`page-item ${currentPage === index + 1 ? "active" : ""
}`}
>
<button
className="page-link "
@ -176,9 +180,8 @@ const Regularization = ({ handleRequest, searchTerm }) => {
</li>
))}
<li
className={`page-item ${
currentPage === totalPages ? "disabled" : ""
}`}
className={`page-item ${currentPage === totalPages ? "disabled" : ""
}`}
>
<button
className="page-link "

View File

@ -185,21 +185,22 @@ export const ReportTask = ({ report, closeModal }) => {
)}
</div>
</div>
<div className="col-12 text-center my-2">
<button type="submit" className="btn btn-sm btn-primary me-3" disabled={isPending}>
{isPending ? "Please wait" : "Submit Report"}
</button>
<div className="col-12 text-end my-2 mt-4">
<button
type="button"
className="btn btn-sm btn-label-secondary"
className="btn btn-sm btn-label-secondary me-3"
onClick={handleClose}
disabled={isPending}
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary" disabled={isPending}>
{isPending ? "Please wait" : "Submit Report"}
</button>
</div>
</form>
</div>
);
};
export default ReportTask;
export default ReportTask;

View File

@ -10,6 +10,7 @@ import { getBgClassFromHash } from "../../utils/projectStatus";
import { cacheData, getCachedData } from "../../slices/apiDataManager";
import ImagePreview from "../common/ImagePreview";
import { useAuditStatus, useSubmitTaskComment } from "../../hooks/useTasks";
import Label from "../common/Label";
const ReportTaskComments = ({
commentsData,
@ -291,10 +292,10 @@ const ReportTaskComments = ({
</p>
)}
</div>
<div className="col-6 col-sm-4 text-center align-items-end m-0">
<label htmlFor="workStatus" className="form-label">
<div className="col-6 col-sm-4 text-start align-items-end m-0">
<Label htmlFor="workStatus" className="form-label" required>
Audit Status
</label>
</Label>
<select
id="workStatus"
className={`form-select form-select-sm`}
@ -361,7 +362,7 @@ const ReportTaskComments = ({
<span>
<button
type="button"
className="btn btn-sm btn-secondary"
className="btn btn-sm btn-label-secondary mt-5"
onClick={closeModal}
data-bs-dismiss="modal"
disabled={isPending}
@ -370,7 +371,7 @@ const ReportTaskComments = ({
</button>
<button
type="submit"
className="btn btn-sm btn-primary ms-2"
className="btn btn-sm btn-primary ms-2 mt-5"
disabled={isPending}
>
{isPending

View File

@ -98,42 +98,42 @@ const AttendanceOverview = () => {
colors: roles.map((_, i) => flatColors[i % flatColors.length]),
};
return (
<div
className="bg-white p-4 rounded shadow d-flex flex-column"
>
{/* Header */}
<div className="d-flex justify-content-between align-items-center mb-3">
<div className="card-title mb-0 text-start">
<h5 className="mb-1">Attendance Overview</h5>
<p className="card-subtitle">Role-wise present count</p>
</div>
<div className="d-flex gap-2">
<select
className="form-select form-select-sm"
value={dayRange}
onChange={(e) => setDayRange(Number(e.target.value))}
>
<option value={7}>Last 7 Days</option>
<option value={15}>Last 15 Days</option>
<option value={30}>Last 30 Days</option>
</select>
<button
className={`btn btn-sm ${view === "chart" ? "btn-primary" : "btn-outline-primary"}`}
onClick={() => setView("chart")}
title="Chart View"
>
<i className="bx bx-bar-chart-alt-2"></i>
</button>
<button
className={`btn btn-sm ${view === "table" ? "btn-primary" : "btn-outline-primary"}`}
onClick={() => setView("table")}
title="Table View"
>
<i className="bx bx-task text-success"></i>
</button>
</div>
</div>
return (
<div
className="bg-white p-4 rounded shadow d-flex flex-column"
>
{/* Header */}
<div className="d-flex justify-content-between align-items-center mb-3">
<div className="card-title mb-0 text-start">
<h5 className="mb-1 fw-bold">Attendance Overview</h5>
<p className="card-subtitle">Role-wise present count</p>
</div>
<div className="d-flex gap-2">
<select
className="form-select form-select-sm"
value={dayRange}
onChange={(e) => setDayRange(Number(e.target.value))}
>
<option value={7}>Last 7 Days</option>
<option value={15}>Last 15 Days</option>
<option value={30}>Last 30 Days</option>
</select>
<button
className={`btn btn-sm ${view === "chart" ? "btn-primary" : "btn-outline-primary"}`}
onClick={() => setView("chart")}
title="Chart View"
>
<i className="bx bx-bar-chart-alt-2"></i>
</button>
<button
className={`btn btn-sm ${view === "table" ? "btn-primary" : "btn-outline-primary"}`}
onClick={() => setView("table")}
title="Table View"
>
<i className="bx bx-task text-success"></i>
</button>
</div>
</div>
{/* Content */}
<div className="flex-grow-1 d-flex align-items-center justify-content-center">

View File

@ -19,7 +19,7 @@ const ProjectCompletionChart = () => {
<div className="card h-100">
<div className="card-header d-flex align-items-start justify-content-between">
<div className="card-title mb-0 text-start">
<h5 className="mb-1">Projects</h5>
<h5 className="mb-1 fw-bold ">Projects</h5>
<p className="card-subtitle">Projects Completion Status</p>
</div>
</div>

View File

@ -90,7 +90,7 @@ const ProjectProgressChart = ({
<div className="d-flex flex-wrap justify-content-between align-items-start mb-2">
{/* Left: Title */}
<div className="card-title text-start">
<h5 className="mb-1">Project Progress</h5>
<h5 className="mb-1 fw-bold">Project Progress</h5>
<p className="card-subtitle">Progress Overview by Project</p>
</div>
</div>

View File

@ -23,6 +23,7 @@ import { useProjects } from "../../hooks/useProjects";
import SelectMultiple from "../common/SelectMultiple";
import { ContactSchema } from "./DirectorySchema";
import InputSuggestions from "../common/InputSuggestion";
import Label from "../common/Label";
const ManageDirectory = ({ submitContact, onCLosed }) => {
const selectedMaster = useSelector(
@ -171,11 +172,11 @@ const ManageDirectory = ({ submitContact, onCLosed }) => {
<FormProvider {...methods}>
<form className="p-2 p-sm-0" onSubmit={handleSubmit(onSubmit)}>
<div className="d-flex justify-content-center align-items-center">
<h6 className="m-0 fw-18"> Create New Contact</h6>
<h5 className="m-0 fw-18"> Create New Contact</h5>
</div>
<div className="row">
<div className="col-md-6 text-start">
<label className="form-label">Name</label>
<Label className="form-label" required>Name</Label>
<input
className="form-control form-control-sm"
{...register("name")}
@ -186,7 +187,7 @@ const ManageDirectory = ({ submitContact, onCLosed }) => {
</div>
<div className="col-md-6 text-start">
<label className="form-label">Organization</label>
<Label className="form-label" required>Organization</Label>
<InputSuggestions
organizationList={organizationList}
value={getValues("organization") || ""}
@ -197,7 +198,7 @@ const ManageDirectory = ({ submitContact, onCLosed }) => {
</div>
<div className="row mt-1">
<div className="col-md-6 text-start">
<label className="form-label">Designation</label>
<Label className="form-label" required>Designation</Label>
<input
className="form-control form-control-sm"
{...register("designation")}
@ -431,7 +432,7 @@ const ManageDirectory = ({ submitContact, onCLosed }) => {
</div>
<div className="row">
<div className="col-md-12 mt-1 text-start">
<label className="form-label ">Select Bucket</label>
<Label className="form-label" required>Select Bucket</Label>
<ul className="d-flex flex-wrap px-1 list-unstyled mb-0">
{bucketsLoaging && <p>Loading...</p>}
@ -475,8 +476,8 @@ const ManageDirectory = ({ submitContact, onCLosed }) => {
/>
</div>
<div className="col-12 text-start">
<label className="form-label">Description</label>
<div className="col-12 text-start mt-1">
<Label className="form-label" required>Description</Label>
<textarea
className="form-control form-control-sm"
rows="2"
@ -487,10 +488,7 @@ const ManageDirectory = ({ submitContact, onCLosed }) => {
)}
</div>
<div className="d-flex justify-content-center gap-1 py-2">
<button className="btn btn-sm btn-primary" type="submit">
{IsSubmitting ? "Please Wait..." : "Submit"}
</button>
<div className="d-flex justify-content-end gap-2 py-2 mt-3">
<button
className="btn btn-sm btn-secondary"
type="button"
@ -498,6 +496,10 @@ const ManageDirectory = ({ submitContact, onCLosed }) => {
>
Cancel
</button>
<button className="btn btn-sm btn-primary" type="submit">
{IsSubmitting ? "Please Wait..." : "Submit"}
</button>
</div>
</form>
</FormProvider>

View File

@ -23,6 +23,7 @@ import { useProjects } from "../../hooks/useProjects";
import SelectMultiple from "../common/SelectMultiple";
import { ContactSchema } from "./DirectorySchema";
import InputSuggestions from "../common/InputSuggestion";
import Label from "../common/Label";
const UpdateContact = ({ submitContact, existingContact, onCLosed }) => {
const selectedMaster = useSelector(
@ -208,7 +209,7 @@ const UpdateContact = ({ submitContact, existingContact, onCLosed }) => {
<FormProvider {...methods}>
<form className="p-2 p-sm-0" onSubmit={handleSubmit(onSubmit)}>
<div className="d-flex justify-content-center align-items-center">
<h6 className="m-0 fw-18"> Update Contact</h6>
<h5 className="m-0 fw-18"> Update Contact</h5>
</div>
<div className="row">
<div className="col-md-6 text-start">
@ -239,7 +240,7 @@ const UpdateContact = ({ submitContact, existingContact, onCLosed }) => {
</div>
<div className="row mt-1">
<div className="col-md-6 text-start">
<label className="form-label">Designation</label>
<Label className="form-label" required>Designation</Label>
<input
className="form-control form-control-sm"
{...register("designation")}
@ -529,22 +530,22 @@ const UpdateContact = ({ submitContact, existingContact, onCLosed }) => {
)}
</div>
<div className="d-flex justify-content-center gap-1 py-2">
<div className="d-flex justify-content-end gap-2 py-0 mt-4">
<button
className="btn btn-sm btn-primary"
type="submit"
disabled={IsSubmitting}
>
{IsSubmitting ? "Please Wait..." : "Update"}
</button>
<button
className="btn btn-sm btn-secondary"
className="btn btn-sm btn-label-secondary"
type="button"
onClick={handleClosed}
disabled={IsSubmitting}
>
Cancel
</button>
<button
className="btn btn-sm btn-primary"
type="submit"
disabled={IsSubmitting}
>
{IsSubmitting ? "Please Wait..." : "Update"}
</button>
</div>
</form>
</FormProvider>

View File

@ -17,6 +17,8 @@ import {
} from "../../slices/apiDataManager";
import { clearApiCacheKey } from "../../slices/apiCacheSlice";
import { useMutation } from "@tanstack/react-query";
import Label from "../common/Label";
import DatePicker from "../common/DatePicker";
const mobileNumberRegex = /^[0-9]\d{9}$/;
@ -220,10 +222,10 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
return (
<>
<form onSubmit={handleSubmit(onSubmit)} className="p-sm-0 p-2">
<div className="text-center"><p className="fs-6 fw-semibold"> {employee ? "Update Employee" : "Create Employee"}</p> </div>
<div className="text-center"><p className="fs-5 fw-semibold"> {employee ? "Update Employee" : "Create Employee"}</p> </div>
<div className="row mb-3">
<div className="col-sm-4">
<div className="form-text text-start">First Name</div>
<Label className="form-text text-start" required>First Name</Label>
<input
type="text"
name="firstName"
@ -272,7 +274,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
</div>
<div className="col-sm-4">
<div className="form-text text-start">Last Name</div>
<Label className="form-text text-start" required>Last Name</Label>
<input
type="text"
{...register("lastName", {
@ -319,7 +321,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
)}
</div>
<div className="col-sm-6">
<div className="form-text text-start">Phone Number</div>
<Label className="form-text text-start" required>Phone Number</Label>
<input
type="text"
keyboardType="numeric"
@ -343,7 +345,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
<div className="row mb-3"></div>
<div className="row mb-3">
<div className="col-sm-4">
<div className="form-text text-start">Gender</div>
<Label className="form-text text-start" required>Gender</Label>
<div className="input-group">
<select
@ -370,41 +372,43 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
)}
</div>
<div className="col-sm-4">
<div className="form-text text-start">Birth Date</div>
<Label className="form-text text-start" required>
Birth Date
</Label>
<div className="input-group">
<input
className="form-control form-control-sm"
type="date"
{...register("birthDate")}
id="birthDate"
<DatePicker
name="birthDate"
control={control} // from useForm()
placeholder="DD-MM-YYYY"
maxDate={new Date()} // restrict future dates (e.g., birth date must be today or past)
className="w-100"
/>
</div>
{errors.birthDate && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
<div className="danger-text text-start" style={{ fontSize: "12px" }}>
{errors.birthDate.message}
</div>
)}
</div>
<div className="col-sm-4">
<div className="form-text text-start">Joining Date</div>
<Label className="form-text text-start" required>
Joining Date
</Label>
<div className="input-group">
<input
className="form-control form-control-sm"
type="date"
{...register("joiningDate")}
id="joiningDate"
<DatePicker
name="joiningDate"
control={control} // from useForm()
placeholder="DD-MM-YYYY"
// For joining date, we dont block future dates
className="w-100"
/>
</div>
{errors.joiningDate && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
<div className="danger-text text-start" style={{ fontSize: "12px" }}>
{errors.joiningDate.message}
</div>
)}
@ -412,7 +416,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
</div>
<div className="row mb-3">
<div className="col-sm-6">
<div className="form-text text-start">Current Address</div>
<Label className="form-text text-start" required>Current Address</Label>
<textarea
id="currentAddress"
@ -444,9 +448,9 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
)}
</div>
<div className="col-sm-6">
<div className="form-text text-start">
<Label className="form-text text-start" required>
Permanent Address
</div>
</Label>
<textarea
id="permanentAddress"
@ -484,7 +488,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
</div>
<div className="row mb-3">
<div className="col-sm-4">
<div className="form-text text-start">Official Designation</div>
<Label className="form-text text-start" required>Official Designation</Label>
<div className="input-group">
<select
className="form-select form-select-sm"
@ -514,9 +518,9 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
)}
</div>
<div className="col-sm-4">
<div className="form-text text-start">
<Label className="form-text text-start" required>
Emergency Contact Person
</div>
</Label>
<input
type="text"
{...register("emergencyContactPerson")}
@ -535,9 +539,9 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
)}
</div>
<div className="col-sm-4">
<div className="form-text text-start">
<Label className="form-text text-start" required>
Emergency Phone Number
</div>
</Label>
<input
type="text"
{...register("emergencyPhoneNumber")}
@ -606,8 +610,16 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
</div>
)}
<div className="row justify-content-start">
<div className="row text-end">
<div className="col-sm-12">
<button
aria-label="manage employee"
type="reset"
className="btn btn-sm btn-label-secondary me-2"
disabled={isPending}
>
Clear
</button>
<button
aria-label="manage employee"
type="submit"
@ -621,14 +633,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
: "Create"}
</button>
<button
aria-label="manage employee"
type="reset"
className="btn btn-sm btn-secondary ms-2"
disabled={isPending}
>
Clear
</button>
</div>
</div>
</form>

View File

@ -114,7 +114,7 @@ const ManageRole = ( {employeeId, onClosed} ) =>
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="text-start mb-3">
<p className="lead">Select Roles</p>
<h5 className="lead">Select Roles :</h5>
</div>
{isLoadingData ? (
@ -148,18 +148,18 @@ const ManageRole = ( {employeeId, onClosed} ) =>
</div>
)}
<div className="text-center mt-3">
<button type="submit" className="btn btn-sm btn-primary me-3" disabled={isLoading}>
{isLoading ? "Please Wait..." : "Submit"}
</button>
<div className="text-end mt-1">
<button
type="reset"
className="btn btn-sm btn-label-secondary"
type="button"
className="btn btn-sm btn-label-secondary me-2"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary" disabled={isLoading}>
{isLoading ? "Please Wait..." : "Submit"}
</button>
</div>
</form>
);

View File

@ -27,6 +27,7 @@ import ExpenseSkeleton from "./ExpenseSkeleton";
import moment from "moment";
import DatePicker from "../common/DatePicker";
import ErrorPage from "../../pages/ErrorPage";
import Label from "../common/Label";
const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
const {
@ -213,9 +214,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
{expenseToEdit ? "Update Expense " : "Create New Expense"}
</h5>
<form id="expenseForm" onSubmit={handleSubmit(onSubmit)}>
<div className="row my-2">
<div className="row my-2 text-start">
<div className="col-md-6">
<label className="form-label">Select Project</label>
<Label className="form-label" required>Select Project</Label>
<select
className="form-select form-select-sm"
{...register("projectId")}
@ -237,9 +238,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
<div className="col-md-6">
<label htmlFor="expensesTypeId" className="form-label">
<Label htmlFor="expensesTypeId" className="form-label" required>
Expense Type
</label>
</Label>
<select
className="form-select form-select-sm"
id="expensesTypeId"
@ -266,11 +267,11 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
</div>
<div className="row my-2">
<div className="row my-2 text-start">
<div className="col-md-6">
<label htmlFor="paymentModeId" className="form-label">
<Label htmlFor="paymentModeId" className="form-label" required>
Payment Mode
</label>
</Label>
<select
className="form-select form-select-sm"
id="paymentModeId"
@ -297,9 +298,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
<div className="col-md-6">
<label htmlFor="paidById" className="form-label ">
<Label htmlFor="paidById" className="form-label" required>
Paid By
</label>
</Label>
<select
className="form-select form-select-sm"
id="paymentModeId"
@ -325,11 +326,11 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
</div>
<div className="row my-2">
<div className="row my-2 text-start">
<div className="col-md-6">
<label htmlFor="transactionDate" className="form-label ">
<Label htmlFor="transactionDate" className="form-label" required>
Transaction Date
</label>
</Label>
<DatePicker name="transactionDate" control={control} />
{errors.transactionDate && (
@ -340,9 +341,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
<div className="col-md-6">
<label htmlFor="amount" className="form-label ">
<Label htmlFor="amount" className="form-label" required>
Amount
</label>
</Label>
<input
type="number"
id="amount"
@ -358,11 +359,11 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
</div>
<div className="row my-2">
<div className="row my-2 text-start">
<div className="col-md-6">
<label htmlFor="supplerName" className="form-label ">
<Label htmlFor="supplerName" className="form-label" required>
Supplier Name/Transporter Name/Other
</label>
</Label>
<input
type="text"
id="supplerName"
@ -377,9 +378,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
<div className="col-md-6">
<label htmlFor="location" className="form-label ">
<Label htmlFor="location" className="form-label" required>
Location
</label>
</Label>
<input
type="text"
id="location"
@ -391,7 +392,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
)}
</div>
</div>
<div className="row my-2">
<div className="row my-2 text-start">
<div className="col-md-6">
<label htmlFor="statusId" className="form-label ">
Transaction ID
@ -428,7 +429,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
{ExpenseType?.noOfPersonsRequired && (
<div className="col-md-6 mt-2">
<div className="col-md-6 mt-2 text-start">
<label className="form-label ">No. of Persons</label>
<input
type="number"
@ -446,9 +447,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
)}
</div>
<div className="row my-2">
<div className="row my-2 text-start">
<div className="col-md-12">
<label htmlFor="description" className="form-label ">Description</label>
<Label htmlFor="description" className="form-label" required>Description</Label>
<textarea
id="description"
className="form-control form-control-sm"
@ -463,16 +464,16 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
</div>
<div className="row my-2">
<div className="row my-2 text-start">
<div className="col-md-12">
<label className="form-label ">Upload Bill </label>
<Label className="form-label" required>Upload Bill </Label>
<div
className="border border-secondary border-dashed rounded p-4 text-center bg-textMuted position-relative"
style={{ cursor: "pointer" }}
onClick={() => document.getElementById("billAttachments").click()}
>
<i className="bx bx-cloud-upload d-block bx-lg"></i>
<i className="bx bx-cloud-upload d-block bx-lg"> </i>
<span className="text-muted d-block">
Click to select or click here to browse
</span>
@ -547,8 +548,16 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</div>
</div>
<div className="d-flex justify-content-center gap-3">
<div className="d-flex justify-content-end gap-3">
{" "}
<button
type="reset"
disabled={isPending || createPending}
onClick={handleClose}
className="btn btn-label-secondary btn-sm mt-3"
>
Cancel
</button>
<button
type="submit"
className="btn btn-primary btn-sm mt-3"
@ -560,14 +569,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
? "Update"
: "Submit"}
</button>
<button
type="reset"
disabled={isPending || createPending}
onClick={handleClose}
className="btn btn-secondary btn-sm mt-3"
>
Cancel
</button>
</div>
</form>
</div>

View File

@ -28,6 +28,7 @@ import EmployeeSearchInput from "../common/EmployeeSearchInput";
import { z } from "zod";
import moment from "moment";
import ExpenseStatusLogs from "./ExpenseStatusLogs";
import Label from "../common/Label";
const ViewExpense = ({ ExpenseId }) => {
const { data, isLoading, isError, error, isFetching } = useExpense(ExpenseId);
@ -418,7 +419,7 @@ const ViewExpense = ({ ExpenseId }) => {
{((nextStatusWithPermission.length > 0 && !IsRejectedExpense) ||
(IsRejectedExpense && isCreatedBy)) && (
<>
<label className="form-label me-2 mb-0">Comment:</label>
<Label className="form-label me-2 mb-0" required>Comment</Label>
<textarea
className="form-control form-control-sm"
{...register("comment")}
@ -434,13 +435,13 @@ const ViewExpense = ({ ExpenseId }) => {
{nextStatusWithPermission?.length > 0 &&
(!IsRejectedExpense || isCreatedBy) && (
<div className="text-center flex-wrap gap-2 my-2">
<div className="text-end flex-wrap gap-2 my-2 mt-3">
{nextStatusWithPermission.map((status, index) => (
<button
key={status.id || index}
type="button"
onClick={() => {
setClickedStatusId(status.id);
setClickedStatusId(status.id);
setValue("statusId", status.id);
handleSubmit(onSubmit)();
}}

View File

@ -51,13 +51,13 @@ const AboutProject = () => {
)}
{projects_Details && (
<>
<div className="card mb-6">
<div className="card mb-4">
<div className="card-header text-start">
<h6 className="card-action-title mb-0 ps-1">
<h5 className="card-action-title mb-0 ps-1">
{" "}
<i className="fa fa-building rounded-circle text-primary"></i>
<span className="ms-2">Project Profile</span>
</h6>
<span className="ms-2 fw-bold">Project Profile</span>
</h5>
</div>
<div className="card-body">
<ul className="list-unstyled my-3 ps-0">

View File

@ -12,6 +12,7 @@ import showToast from "../../services/toastService";
import { useProjectDetails } from "../../hooks/useProjects";
import eventBus from "../../services/eventBus";
import { useCreateTask } from "../../hooks/useTasks";
import Label from "../common/Label";
const AssignTask = ({ assignData, onClose, setAssigned }) => {
const maxPlanned =
@ -261,8 +262,8 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
<div className="dropdown position-relative d-inline-block">
<a
className={`dropdown-toggle hide-arrow cursor-pointer ${selectedRoles.includes("all") || selectedRoles.length === 0
? "text-secondary"
: "text-primary"
? "text-secondary"
: "text-primary"
}`}
data-bs-toggle="dropdown"
role="button"
@ -427,7 +428,7 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
) : (
<div className="col-12">
<p className="text-center">
No employees found for the selected role.
No employees found for the selected role.
</p>
</div>
)}
@ -502,8 +503,11 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
<div className="col-md text-start mx-0 px-0">
<div className="form-check form-check-inline mt-2 px-1 mb-2 text-start">
<label className="text-dark d-flex align-items-center flex-wrap form-text">
<span>Target for Today</span>&nbsp;
<span style={{ marginLeft: "46px" }}>:</span>
<Label htmlFor="targetToday" required className="me-1">
Target for Today
</Label>
<span style={{ marginLeft: "37px" }}>:</span>
</label>
</div>
<div
@ -533,12 +537,16 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
)}
</div>
<label
{/* <label
className="form-text fs-7 m-1 text-lg text-dark"
htmlFor="descriptionTextarea" // Changed htmlFor for better accessibility
>
Description
</label>
</label> */}
<Label className="form-text fs-7 m-1 text-lg text-dark"
htmlFor="descriptionTextarea" required>
Description
</Label>
<Controller
name="description"
control={control}
@ -552,14 +560,7 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
</div>
{/* Submit and Cancel buttons */}
<div className="col-12 d-flex justify-content-center align-items-center gap-sm-6 gap-8 text-center mt-1">
<button
type="submit"
className="btn btn-sm btn-primary "
disabled={isSubmitting || loading}
>
{isSubmitting ? "Please Wait" : "Submit"}
</button>
<div className="col-12 d-flex justify-content-end align-items-center gap-2 mt-6">
<button
type="reset"
className="btn btn-sm btn-label-secondary"
@ -570,7 +571,15 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
>
Cancel
</button>
<button
type="submit"
className="btn btn-sm btn-primary"
disabled={isSubmitting || loading}
>
{isSubmitting ? "Please Wait" : "Submit"}
</button>
</div>
</form>
</div>
</div>

View File

@ -7,6 +7,7 @@ import { getCachedData } from "../../../slices/apiDataManager";
import showToast from "../../../services/toastService";
import { useManageProjectInfra } from "../../../hooks/useProjects";
import useSelect from "../../common/useSelect";
import Label from "../../common/Label";
const buildingSchema = z.object({
Id: z.string().optional(),
@ -100,7 +101,7 @@ const BuildingModel = ({ project, onClose, editingBuilding = null }) => {
return (
<form onSubmit={handleSubmit(onSubmitHandler)} className="row g-2">
<h5 className="text-center mb-2">Manage Buildings </h5>
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Select Building</label>
<select
{...register("Id")}
@ -121,10 +122,10 @@ const BuildingModel = ({ project, onClose, editingBuilding = null }) => {
</div>
{/* Name */}
<div className="col-12">
<label className="form-label">
<div className="col-12 text-start">
<Label className="form-label" required>
{watchedId !== "0" ? "Rename Building Name" : "New Building Name"}
</label>
</Label>
<input
{...register("name")}
type="text"
@ -136,8 +137,8 @@ const BuildingModel = ({ project, onClose, editingBuilding = null }) => {
</div>
{/* Description */}
<div className="col-12">
<label className="form-label">Description</label>
<div className="col-12 text-start">
<Label className="form-label" required>Description</Label>
<textarea
{...register("description")}
rows="5"
@ -149,10 +150,21 @@ const BuildingModel = ({ project, onClose, editingBuilding = null }) => {
)}
</div>
<div className="col-12 text-center">
<div className="col-12 text-end mt-5">
<button
type="reset"
className="btn btn-sm btn-label-secondary me-3"
disabled={isPending}
onClick={() => {
onClose();
reset();
}}
>
Cancel
</button>
<button
type="submit"
className="btn btn-sm btn-primary me-3"
className="btn btn-sm btn-primary"
disabled={isPending}
>
{isPending
@ -162,17 +174,7 @@ const BuildingModel = ({ project, onClose, editingBuilding = null }) => {
: "Add Building"}
</button>
<button
type="reset"
className="btn btn-sm btn-label-secondary"
disabled={isPending}
onClick={() => {
onClose();
reset();
}}
>
Cancel
</button>
</div>
</form>
);

View File

@ -134,7 +134,7 @@ useEffect(() => {
<h5 className="mb-1">Manage Task</h5>
</div>
<div className="row g-2">
<div className="row g-2 text-start">
<div className="col-12 col-md-6">
<label className="form-label">Select Building</label>
<input
@ -154,7 +154,7 @@ useEffect(() => {
</div>
</div>
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Select Work Area</label>
<input
className="form-control form-control-sm"
@ -163,7 +163,7 @@ useEffect(() => {
/>
</div>
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Select Activity</label>
<select
{...register("activityID")}
@ -185,7 +185,7 @@ useEffect(() => {
)}
</div>
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Select Work Category</label>
<select
{...register("workCategoryId")}
@ -207,7 +207,7 @@ useEffect(() => {
)}
</div>
<div className="col-5">
<div className="col-5 text-start">
<label className="form-label">Planned Work</label>
<input
{...register("plannedWork", { valueAsNumber: true })}
@ -219,7 +219,7 @@ useEffect(() => {
)}
</div>
<div className="col-5">
<div className="col-5 text-start">
<label className="form-label">Completed Work</label>
<input
{...register("completedWork", { valueAsNumber: true })}
@ -232,7 +232,7 @@ useEffect(() => {
)}
</div>
<div className="col-2">
<div className="col-2 text-start">
<label className="form-label">Unit</label>
<input
className="form-control form-control-sm"
@ -241,7 +241,7 @@ useEffect(() => {
/>
</div>
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Comment</label>
<textarea {...register("comment")} rows="2" className="form-control" />
{errors.comment && (
@ -249,22 +249,22 @@ useEffect(() => {
)}
</div>
<div className="col-12 text-center">
<button
type="submit"
className="btn btn-sm btn-primary me-2"
disabled={isPending}
>
{isPending ? "Please Wait..." : "Edit Task"}
</button>
<div className="col-12 text-end mt-5">
<button
type="button"
className="btn btn-sm btn-label-secondary"
className="btn btn-sm btn-label-secondary me-2"
onClick={onClose}
disabled={isPending}
>
Cancel
</button>
<button
type="submit"
className="btn btn-sm btn-primary"
disabled={isPending}
>
{isPending ? "Please Wait..." : "Edit Task"}
</button>
</div>
</form>
);

View File

@ -5,6 +5,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import showToast from "../../../services/toastService";
import { useManageProjectInfra } from "../../../hooks/useProjects";
import { useSelector } from "react-redux";
import Label from "../../common/Label";
// Schema
const floorSchema = z.object({
@ -101,8 +102,8 @@ const FloorModel = ({ project, onClose, onSubmit }) => {
<div className="text-center mb-1">
<h5 className="mb-1">Manage Floor</h5>
</div>
<div className="col-12">
<label className="form-label">Select Building</label>
<div className="col-12 text-start">
<Label className="form-label" required>Select Building</Label>
<select
{...register("buildingId")}
className="form-select form-select-sm"
@ -126,7 +127,7 @@ const FloorModel = ({ project, onClose, onSubmit }) => {
{watchBuildingId !== "0" && (
<>
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Select Floor</label>
<select
{...register("id")}
@ -146,10 +147,10 @@ const FloorModel = ({ project, onClose, onSubmit }) => {
</select>
</div>
<div className="col-12">
<label className="form-label">
<div className="col-12 text-start">
<Label className="form-label" required>
{watchId !== "0" ? "Edit Floor Name" : "New Floor Name"}
</label>
</Label>
<input
{...register("floorName")}
className="form-control form-control-sm"
@ -162,10 +163,18 @@ const FloorModel = ({ project, onClose, onSubmit }) => {
</>
)}
<div className="col-12 text-center">
<div className="col-12 text-end mt-5">
<button
type="button"
className="btn btn-sm btn-label-secondary me-3"
disabled={isPending}
onClick={onClose}
>
Cancel
</button>
<button
type="submit"
className="btn btn-sm btn-primary me-3"
className="btn btn-sm btn-primary"
disabled={isPending}
>
{isPending
@ -174,14 +183,7 @@ const FloorModel = ({ project, onClose, onSubmit }) => {
? "Edit Floor"
: "Add Floor"}
</button>
<button
type="button"
className="btn btn-sm btn-label-secondary"
disabled={isPending}
onClick={onClose}
>
Cancel
</button>
</div>
</form>
);

View File

@ -8,6 +8,7 @@ import {
} from "../../../hooks/masterHook/useMaster";
import { useManageTask } from "../../../hooks/useProjects";
import showToast from "../../../services/toastService";
import Label from "../../common/Label";
const taskSchema = z.object({
buildingID: z.string().min(1, "Building is required"),
@ -106,8 +107,8 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
<div className="text-center mb-1">
<h5 className="mb-1">Manage Task</h5>
</div>
<div className="col-6">
<label className="form-label">Select Building</label>
<div className="col-6 text-start">
<Label className="form-label" required>Select Building</Label>
<select
className="form-select form-select-sm"
{...register("buildingID")}
@ -128,8 +129,8 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
</div>
{selectedBuilding && (
<div className="col-6">
<label className="form-label">Select Floor</label>
<div className="col-6 text-start">
<Label className="form-label" required>Select Floor</Label>
<select
className="form-select form-select-sm"
{...register("floorId")}
@ -150,8 +151,8 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
)}
{selectedFloor && (
<div className="col-12">
<label className="form-label">Select Work Area</label>
<div className="col-12 text-start">
<Label className="form-label" required>Select Work Area</Label>
<select
className="form-select form-select-sm"
{...register("workAreaId")}
@ -172,8 +173,8 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
)}
{selectedWorkArea && (
<div className="col-12">
<label className="form-label">Select Activity</label>
<div className="col-12 text-start">
<Label className="form-label" required>Select Activity</Label>
<select
className="form-select form-select-sm"
{...register("activityID")}
@ -192,7 +193,7 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
)}
{selectedWorkArea && (
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Select Work Category</label>
<select
className="form-select form-select-sm"
@ -212,8 +213,8 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
{selectedActivity && selectedCategory && (
<>
<div className="col-5">
<label className="form-label">Planned Work</label>
<div className="col-5 text-start">
<Label className="form-label" required>Planned Work</Label>
<input
type="number"
className="form-control form-control-sm"
@ -223,7 +224,7 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
<p className="danger-text">{errors.plannedWork.message}</p>
)}
</div>
<div className="col-5">
<div className="col-5 text-start">
<label className="form-label">Completed Work</label>
<input
type="number"
@ -234,7 +235,7 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
<p className="danger-text">{errors.completedWork.message}</p>
)}
</div>
<div className="col-2">
<div className="col-2 text-start">
<label className="form-label">Unit</label>
<input
type="text"
@ -247,7 +248,7 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
)}
{selectedActivity && selectedCategory && (
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Comment</label>
<textarea
className="form-control"
@ -260,21 +261,21 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
</div>
)}
<div className="col-12 text-center">
<button
type="submit"
className="btn btn-sm btn-primary me-3"
disabled={isSubmitting}
>
{isSubmitting ? "Please Wait..." : "Add Task"}
</button>
<div className="col-12 text-end mt-5">
<button
type="button"
className="btn btn-sm btn-label-secondary"
className="btn btn-sm btn-label-secondary me-3"
onClick={onClose}
>
Cancel
</button>
<button
type="submit"
className="btn btn-sm btn-primary"
disabled={isSubmitting}
>
{isSubmitting ? "Please Wait..." : "Add Task"}
</button>
</div>
</form>
);

View File

@ -5,13 +5,14 @@ import { z } from "zod";
import showToast from "../../../services/toastService";
import { useManageProjectInfra } from "../../../hooks/useProjects";
import { useSelector } from "react-redux";
import Label from "../../common/Label";
const workAreaSchema = z.object({
id: z.string().optional(),
buildingId: z.string().refine((val) => val !== "0", {
message: "Building is required",
}),
floorId: z.string().refine((val)=>val !== "0",{message:"Floor is required"}),
message: "Building is required",
}),
floorId: z.string().refine((val) => val !== "0", { message: "Floor is required" }),
areaName: z.string().min(3, "Work Area Name must be at least 3 characters"),
});
@ -25,7 +26,7 @@ const defaultModel = {
const WorkAreaModel = ({ project, onSubmit, onClose }) => {
const [selectedBuilding, setSelectedBuilding] = useState(null);
const [selectedFloor, setSelectedFloor] = useState(null);
const selectedProject = useSelector((store)=>store.localVariables.projectId)
const selectedProject = useSelector((store) => store.localVariables.projectId)
const {
register,
handleSubmit,
@ -84,8 +85,7 @@ const WorkAreaModel = ({ project, onSubmit, onClose }) => {
reset(defaultModel);
}, []);
const onSubmitForm = ( data ) =>
{
const onSubmitForm = (data) => {
const payload = {
id: data.id === "0" ? null : data.id,
areaName: data.areaName,
@ -108,51 +108,51 @@ const WorkAreaModel = ({ project, onSubmit, onClose }) => {
<div className="text-center mb-1">
<h5 className="mb-1">Manage Work Area</h5>
</div>
<div className="col-12 col-sm-6">
<label className="form-label">Select Building</label>
<div className="col-12 col-sm-6 text-start">
<Label className="form-label" required>Select Building</Label>
<select
{...register("buildingId")}
className="form-select form-select-sm"
>
<option value="0">Select Building</option>
{project?.map((b) => (
<option key={b.id} value={b.id}>
{b.buildingName}
</option>
))}
</select>
{errors.buildingId && (
<p className="danger-text">{errors.buildingId.message}</p>
)}
</div>
{watchBuildingId !== "0" && (
<div className="col-12 col-sm-6 text-start">
<Label className="form-label" required>Select Floor</Label>
<select
{...register("buildingId")}
{...register("floorId")}
className="form-select form-select-sm"
>
<option value="0">Select Building</option>
{project?.map((b) => (
<option key={b.id} value={b.id}>
{b.buildingName}
<option value="0">
{selectedBuilding?.floor?.length > 0
? "NO Floor Found"
: "Select Floor"}
</option>
{selectedBuilding?.floors?.map((f) => (
<option key={f.id} value={f.id}>
{f.floorName}
</option>
))}
</select>
{errors.buildingId && (
<p className="danger-text">{errors.buildingId.message}</p>
{errors.floorId && (
<p className="danger-text">{errors.floorId.message}</p>
)}
</div>
{watchBuildingId !== "0" && (
<div className="col-12 col-sm-6">
<label className="form-label">Select Floor</label>
<select
{...register("floorId")}
className="form-select form-select-sm"
>
<option value="0">
{selectedBuilding?.floor?.length > 0
? "NO Floor Found"
: "Select Floor"}
</option>
{selectedBuilding?.floors?.map((f) => (
<option key={f.id} value={f.id}>
{f.floorName}
</option>
))}
</select>
{errors.floorId && (
<p className="danger-text">{errors.floorId.message}</p>
)}
</div>
)}
)}
{watchFloorId !== "0" && (
<>
<div className="col-12">
<div className="col-12 text-start">
<label className="form-label">Select Work Area</label>
<select
{...register("id")}
@ -169,12 +169,12 @@ const WorkAreaModel = ({ project, onSubmit, onClose }) => {
</select>
</div>
<div className="col-12">
<label className="form-label">
<div className="col-12 text-start">
<Label className="form-label" required>
{watchWorkAreaId === "0"
? "Enter Work Area Name"
: "Edit Work Area Name"}
</label>
</Label>
<input
type="text"
className="form-control form-control-sm"
@ -187,14 +187,15 @@ const WorkAreaModel = ({ project, onSubmit, onClose }) => {
</div>
</>
)}
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3" disabled={isPending}>
{isPending ? "Please Wait.." : watchWorkAreaId === "0" ? "Add Work Area" : "Update Work Area"}
</button>
<button type="button" className="btn btn-sm btn-label-secondary" disabled={isPending} onClick={onClose}>
Cancel
</button>
</div>
<div className="col-12 text-end mt-5">
<button type="button" className="btn btn-sm btn-label-secondary me-3" disabled={isPending} onClick={onClose}>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary" disabled={isPending}>
{isPending ? "Please Wait.." : watchWorkAreaId === "0" ? "Add Work Area" : "Update Work Area"}
</button>
</div>
</form>
);
};

View File

@ -2,6 +2,8 @@ import React, { useEffect, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import Label from "../common/Label";
import DatePicker from "../common/DatePicker";
const currentDate = new Date().toLocaleDateString('en-CA');
const formatDate = (date) => {
@ -14,14 +16,14 @@ const formatDate = (date) => {
}
return d.toLocaleDateString('en-CA');
};
const ManageProjectInfo = ({ project, handleSubmitForm, onClose,isPending }) => {
const ManageProjectInfo = ({ project, handleSubmitForm, onClose, isPending }) => {
const [CurrentProject, setCurrentProject] = useState();
const [addressLength, setAddressLength] = useState(0);
const maxAddressLength = 500;
const ACTIVE_STATUS_ID = "b74da4c2-d07e-46f2-9919-e75e49b12731";
const DEFAULT_EMPTY_STATUS_ID = "00000000-0000-0000-0000-000000000000";
const ACTIVE_STATUS_ID = "b74da4c2-d07e-46f2-9919-e75e49b12731";
const DEFAULT_EMPTY_STATUS_ID = "00000000-0000-0000-0000-000000000000";
const projectSchema = z
.object({
...(project?.id ? { id: z.string().optional() } : {}),
@ -93,15 +95,15 @@ const DEFAULT_EMPTY_STATUS_ID = "00000000-0000-0000-0000-000000000000";
reset(
project
? {
id: project?.id || "",
name: project?.name || "",
shortName: project?.shortName || "",
contactPerson: project?.contactPerson || "",
projectAddress: project?.projectAddress || "",
startDate: formatDate(project?.startDate) || "",
endDate: formatDate(project?.endDate) || "",
projectStatusId: String(project?.projectStatus?.id) || "00000000-0000-0000-0000-000000000000",
}
id: project?.id || "",
name: project?.name || "",
shortName: project?.shortName || "",
contactPerson: project?.contactPerson || "",
projectAddress: project?.projectAddress || "",
startDate: formatDate(project?.startDate) || "",
endDate: formatDate(project?.endDate) || "",
projectStatusId: String(project?.projectStatus?.id) || "00000000-0000-0000-0000-000000000000",
}
: {}
);
setAddressLength(project?.projectAddress?.length || 0);
@ -115,9 +117,8 @@ const DEFAULT_EMPTY_STATUS_ID = "00000000-0000-0000-0000-000000000000";
*/
const onSubmitForm = ( updatedProject ) =>
{
const onSubmitForm = (updatedProject) => {
handleSubmitForm(updatedProject);
};
@ -137,197 +138,202 @@ const DEFAULT_EMPTY_STATUS_ID = "00000000-0000-0000-0000-000000000000";
return (
<div className="p-sm-2 p-2">
<div className="text-center mb-2">
<h5 className="mb-2">
{project?.id ? "Edit Project" : "Create Project"}
</h5>
</div>
<form className="row g-2" onSubmit={handleSubmit(onSubmitForm)}>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="name">
Project Name
</label>
<input
type="text"
id="name"
name="name"
className="form-control form-control-sm"
placeholder="Project Name"
{...register("name")}
/>
{errors.name && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.name.message}
</div>
)}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="shortName">
Short Name
</label>
<input
type="text"
id="shortName"
name="shortName"
className="form-control form-control-sm"
placeholder="Short Name"
{...register("shortName")}
/>
{errors.shortName && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.shortName.message}
</div>
)}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="contactPerson">
Contact Person
</label>
<input
type="text"
id="contactPerson"
name="contactPerson"
className="form-control form-control-sm"
placeholder="Contact Person"
maxLength={50}
{...register("contactPerson")}
/>
{errors.contactPerson && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.contactPerson.message}
</div>
)}
</div>
<div className="p-sm-2 p-2">
<div className="col-12 col-md-6">
<label className="form-label" htmlFor="startDate">
Start Date
</label>
<input
className="form-control form-control-sm"
type="date"
name="startDate"
{...register("startDate")}
id="startDate"
/>
{errors.startDate && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.startDate.message}
</div>
)}
<div className="text-center mb-2">
<h5 className="mb-2">
{project?.id ? "Edit Project" : "Create Project"}
</h5>
</div>
<form className="row g-2 text-start" onSubmit={handleSubmit(onSubmitForm)}>
<div className="col-12 col-md-12">
<Label htmlFor="name" required>
Project Name
</Label>
<input
type="text"
id="name"
name="name"
className="form-control form-control-sm"
placeholder="Project Name"
{...register("name")}
/>
{errors.name && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.name.message}
</div>
<div className="col-12 col-md-6">
<label className="form-label" htmlFor="endDate">
End Date
</label>
<input
className="form-control form-control-sm"
type="date"
name="endDate"
{...register("endDate")}
id="endDate"
/>
{errors.endDate && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.endDate.message}
</div>
)}
</div>
<div className="col-12 col-md-6">
<label className="form-label" htmlFor="modalEditUserStatus">
Status
</label>
<select
id="modalEditUserStatus"
name="modalEditUserStatus"
className="select2 form-select form-select-sm"
aria-label="Default select example"
{...register("projectStatusId", {
required: "Status is required",
valueAsNumber: false,
})}
>
{/* <option disabled>Status</option>
<option value="b74da4c2-d07e-46f2-9919-e75e49b12731">Active</option> */}
<option value={ACTIVE_STATUS_ID}>Active</option>
<option value="603e994b-a27f-4e5d-a251-f3d69b0498ba">On Hold</option>
<option value="cdad86aa-8a56-4ff4-b633-9c629057dfef">In Progress</option>
<option value="ef1c356e-0fe0-42df-a5d3-8daee355492d">Inactive</option>
<option value="33deaef9-9af1-4f2a-b443-681ea0d04f81">Completed</option>
</select>
{errors.projectStatusId && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.projectStatusId.message}
</div>
)}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="projectAddress">
Project Address
</label>
<div className="input-group">
<textarea
id="projectAddress"
name="projectAddress"
className="form-control"
maxLength={maxAddressLength}
{...register("projectAddress")}
onChange={(e) => {
setAddressLength(e.target.value.length);
}}
/>
</div>
<div className="text-end" style={{ fontSize: "12px" }}>
{maxAddressLength - addressLength} characters left
</div>
{errors.projectAddress && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.projectAddress.message}
</div>
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3" disabled={isPending}>
{isPending ? "Please Wait..." : project?.id ? "Update" : "Submit"}
</button>
<button
type="button"
className="btn btn-sm btn-label-secondary"
onClick={handleCancel}
aria-label="Close"
disabled={isPending}
>
Cancel
</button>
</div>
</form>
)}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="shortName">
Short Name
</label>
<input
type="text"
id="shortName"
name="shortName"
className="form-control form-control-sm"
placeholder="Short Name"
{...register("shortName")}
/>
{errors.shortName && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.shortName.message}
</div>
)}
</div>
<div className="col-12 col-md-12">
<Label htmlFor="contactPerson" required>
Contact Person
</Label>
<input
type="text"
id="contactPerson"
name="contactPerson"
className="form-control form-control-sm"
placeholder="Contact Person"
maxLength={50}
{...register("contactPerson")}
/>
{errors.contactPerson && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.contactPerson.message}
</div>
)}
</div>
<div className="col-12 col-md-6">
<label className="form-label" htmlFor="startDate">
Start Date
</label>
<DatePicker
name="startDate"
control={control}
placeholder="DD-MM-YYYY"
maxDate={new Date()} // optional: restrict future dates
className="w-100"
/>
{errors.startDate && (
<div className="danger-text text-start" style={{ fontSize: "12px" }}>
{errors.startDate.message}
</div>
)}
</div>
<div className="col-12 col-md-6">
<label className="form-label" htmlFor="endDate">
End Date
</label>
<DatePicker
name="endDate"
control={control}
placeholder="DD-MM-YYYY"
minDate={getValues("startDate")} // optional: restrict future dates
className="w-100"
/>
{errors.endDate && (
<div className="danger-text text-start" style={{ fontSize: "12px" }}>
{errors.endDate.message}
</div>
)}
</div>
<div className="col-12 col-md-6">
<label className="form-label" htmlFor="modalEditUserStatus">
Status
</label>
<select
id="modalEditUserStatus"
name="modalEditUserStatus"
className="select2 form-select form-select-sm"
aria-label="Default select example"
{...register("projectStatusId", {
required: "Status is required",
valueAsNumber: false,
})}
>
{/* <option disabled>Status</option>
<option value="b74da4c2-d07e-46f2-9919-e75e49b12731">Active</option> */}
<option value={ACTIVE_STATUS_ID}>Active</option>
<option value="603e994b-a27f-4e5d-a251-f3d69b0498ba">On Hold</option>
<option value="cdad86aa-8a56-4ff4-b633-9c629057dfef">In Progress</option>
<option value="ef1c356e-0fe0-42df-a5d3-8daee355492d">Inactive</option>
<option value="33deaef9-9af1-4f2a-b443-681ea0d04f81">Completed</option>
</select>
{errors.projectStatusId && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.projectStatusId.message}
</div>
)}
</div>
<div className="col-12 col-md-12">
<Label htmlFor="projectAddress" required>
Project Address
</Label>
<div className="input-group">
<textarea
id="projectAddress"
name="projectAddress"
className="form-control"
maxLength={maxAddressLength}
{...register("projectAddress")}
onChange={(e) => {
setAddressLength(e.target.value.length);
}}
/>
</div>
<div className="text-end" style={{ fontSize: "12px" }}>
{maxAddressLength - addressLength} characters left
</div>
{errors.projectAddress && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.projectAddress.message}
</div>
)}
</div>
<div className="col-12 text-end mt-4">
<button
type="button"
className="btn btn-label-secondary btn-sm me-2"
onClick={handleCancel}
aria-label="Close"
disabled={isPending}
>
Cancel
</button>
<button
type="submit"
className="btn btn-primary btn-sm"
disabled={isPending}
>
{isPending ? "Please Wait..." : project?.id ? "Update" : "Submit"}
</button>
</div>
</form>
</div>
);
};

View File

@ -0,0 +1,19 @@
/* For Webkit browsers (Chrome, Edge, Safari) */
.modal-dialog-scrollable::-webkit-scrollbar {
width: 6px; /* smaller width */
}
.modal-dialog-scrollable::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.3); /* scrollbar color */
border-radius: 10px;
}
.modal-dialog-scrollable::-webkit-scrollbar-track {
background: transparent;
}
/* For Firefox */
.modal-dialog-scrollable {
scrollbar-width: thin; /* shrinks scrollbar */
scrollbar-color: rgba(0, 0, 0, 0.3) transparent;
}

View File

@ -4,6 +4,7 @@ import { useAllEmployees } from "../../hooks/useEmployees";
import useSearch from "../../hooks/useSearch";
import AssignEmployeeTable from "./AssignEmployeeTable";
import showToast from "../../services/toastService";
import "./MapUser.css";
const MapUsers = ({
projectId,
@ -118,22 +119,22 @@ const MapUsers = ({
<div className="modal-content">
<div className="modal-header text-center">
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close">
</button>
</button>
</div>
<p className="m-0 fw-semibold fs-5">Assign Employee</p>
<div className="px-4 mt-4 col-md-4 text-start">
{(filteredData.length > 0 ||
allocationEmployeesData.length > 0) && (
<div className="input-group input-group-sm mb-2">
<input
type="search"
className="form-control"
placeholder="Search employees..."
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
)}
<div className="input-group input-group-sm mb-2">
<input
type="search"
className="form-control"
placeholder="Search employees..."
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
)}
<p className="mb-0 small text-muted fw-semibold">Select Employee</p>
</div>
@ -183,24 +184,24 @@ const MapUsers = ({
</tbody>
</table>
</div>
<div className="modal-footer">
{(filteredData.length > 0 ||
allocationEmployeesData.length > 0) && (
<button className="btn btn-sm btn-success" onClick={handleSubmit}>
{assignedLoading ? "Please Wait..." : "Assign to Project"}
</button>
)}
<div className="modal-footer mt-5 d-flex justify-content-end gap-0">
<button
type="button"
className="btn btn-sm btn-secondary"
className="btn btn-sm btn-label-secondary"
data-dismiss="modal"
aria-label="Close"
onClick={onClose}
>
Cancel
</button>
{(filteredData.length > 0 || allocationEmployeesData.length > 0) && (
<button className="btn btn-sm btn-primary" onClick={handleSubmit}>
{assignedLoading ? "Please Wait..." : "Assign to Project"}
</button>
)}
</div>
</div>
</div>
</>

View File

@ -93,7 +93,7 @@ const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
>
<button
type="button"
className="link-button link-button-sm m-1 "
className="link-button link-button-sm m-1 btn-primary"
onClick={()=>setshowModalBuilding(true)}
>
<i className="bx bx-plus-circle me-2"></i>
@ -101,7 +101,7 @@ const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
</button>
<button
type="button"
className="link-button m-1"
className="link-button m-1 btn-primary"
onClick={()=>setshowModalFloor(true)}
>
<i className="bx bx-plus-circle me-2"></i>
@ -109,7 +109,7 @@ const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
</button>
<button
type="button"
className="link-button m-1"
className="link-button m-1 btn-primary"
onClick={() => setshowModalWorkArea(true)}
>
<i className="bx bx-plus-circle me-2"></i>
@ -117,7 +117,7 @@ const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
</button>
<button
type="button"
className="link-button m-1"
className="link-button m-1 btn-primary"
onClick={()=>setshowModalTask(true)}
>
<i className="bx bx-plus-circle me-2"></i>

View File

@ -167,11 +167,11 @@ const ProjectOverview = ({ project }) => {
return (
<div className="card" style={{ minHeight: "490px" }}>
<div className="card-header text-start">
<h6 className="card-action-title mb-0">
<h5 className="card-action-title mb-0">
{" "}
<i className="fa fa-line-chart rounded-circle text-primary"></i>
<span className="ms-2">Project Statistics</span>
</h6>
<span className="ms-2 fw-bold">Project Statistics</span>
</h5>
</div>
<div className="card-body">
<ul className="list-unstyled m-0 p-0">

View File

@ -24,7 +24,7 @@ const ContactInfro = ({ onNext }) => {
}
};
return (
<div className="row g-6">
<div className="row g-6 text-start">
<div className="col-sm-6">
<Label htmlFor="firstName" required>
First Name

View File

@ -56,7 +56,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
return (
<div className="row g-2">
<div className="row g-2 text-start">
<div className="col-sm-6">
<Label htmlFor="organizationName" required>
Organization Name
@ -223,10 +223,10 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
/>
</div>
<div className="d-flex justify-content-between mt-3">
<div className="d-flex justify-content-end mt-3">
<button
type="button"
className="btn btn-sm btn-secondary"
className="btn btn-sm btn-secondary me-3"
onClick={onPrev}
disabled={isPending}
>

View File

@ -233,7 +233,7 @@ const SubScription = ({ onSubmitSubScription, onNext }) => {
</div>
)}
<div className="d-flex text-center mt-4">
<div className="d-flex text-end mt-4">
<button
onClick={handleSubscriptionSubmit}
className="btn btn-sm btn-primary"

View File

@ -8,7 +8,7 @@ const DatePicker = ({
placeholder = "DD-MM-YYYY",
className = "",
allowText = false,
maxDate=new Date(),
maxDate, // removed default new Date()
minDate,
...rest
}) => {
@ -25,19 +25,25 @@ const DatePicker = ({
if (inputRef.current) {
flatpickr(inputRef.current, {
dateFormat: "d-m-Y",
allowInput: allowText,
allowInput: allowText,
defaultDate: value
? flatpickr.parseDate(value, "Y-m-d")
: null,
maxDate:maxDate,
minDate:new Date(minDate?.split("T")[0]) ?? undefined,
onChange: function (selectedDates, dateStr) {
onChange(dateStr);
maxDate: maxDate ?? undefined, // only applied if passed
minDate: minDate ? new Date(minDate.split("T")[0]) : undefined,
onChange: function (selectedDates) {
if (selectedDates.length > 0) {
// store in YYYY-MM-DD
const formatted = flatpickr.formatDate(selectedDates[0], "Y-m-d");
onChange(formatted);
} else {
onChange("");
}
},
...rest
});
}
}, [inputRef]);
}, [inputRef, value, allowText, maxDate, minDate, rest, onChange]);
return (
<div className={` position-relative ${className}`}>
@ -45,8 +51,13 @@ const DatePicker = ({
type="text"
className="form-control form-control-sm "
placeholder={placeholder}
defaultValue={
value ? flatpickr.formatDate(flatpickr.parseDate(value, "Y-m-d"), "d-m-Y") : ""
defaultValue={
value
? flatpickr.formatDate(
flatpickr.parseDate(value, "Y-m-d"),
"d-m-Y"
)
: ""
}
ref={(el) => {
inputRef.current = el;

View File

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

View File

@ -8,6 +8,7 @@ import { clearApiCacheKey } from "../../slices/apiCacheSlice";
import { getCachedData, cacheData } from "../../slices/apiDataManager";
import showToast from "../../services/toastService";
import { useCreateActivity } from "../../hooks/masterHook/useMaster";
import Label from "../common/Label";
const schema = z.object({
activityName: z.string().min(1, { message: "Activity Name is required" }),
@ -118,8 +119,8 @@ const CreateActivity = ({ onClose }) => {
<form onSubmit={handleSubmit(onSubmit)}>
{/* <h6>Create Activity</h6> */}
<div className="row">
<div className="col-6">
<label className="form-label">Activity</label>
<div className="col-6 text-start">
<Label className="form-label" required>Activity</Label>
<input
type="text"
{...register("activityName")}
@ -131,8 +132,8 @@ const CreateActivity = ({ onClose }) => {
)}
</div>
<div className="col-6">
<label className="form-label">Measurement</label>
<div className="col-6 text-start">
<Label className="form-label" required>Measurement</Label>
<input
type="text"
{...register("unitOfMeasurement")}
@ -219,17 +220,17 @@ const CreateActivity = ({ onClose }) => {
</button>
</div>
<div className="col-12 text-center mt-3">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait" : "Submit"}
</button>
<div className="col-12 text-end mt-3">
<button
type="button" // change to button
className="btn btn-sm btn-label-secondary"
type="reset"
className="btn btn-sm btn-label-secondary me-3"
onClick={handleClose}
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading ? "Please Wait" : "Submit"}
</button>
</div>
</div>

View File

@ -6,7 +6,8 @@ import { MasterRespository } from '../../repositories/MastersRepository';
import { clearApiCacheKey } from '../../slices/apiCacheSlice';
import { getCachedData, cacheData } from '../../slices/apiDataManager';
import showToast from '../../services/toastService';
import { useCreateContactCategory } from '../../hooks/masterHook/useMaster';
import {useCreateContactCategory} from '../../hooks/masterHook/useMaster';
import Label from '../common/Label';
const schema = z.object({
@ -64,17 +65,17 @@ const CreateContactCategory = ({ onClose }) => {
}, []);
return (<>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
<label className="form-label">Category Name</label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">Description</label>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Category Name</Label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>Description</Label>
<textarea
rows="3"
{...register("description")}
@ -92,21 +93,19 @@ const CreateContactCategory = ({ onClose }) => {
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button" // not reset
className="btn btn-sm btn-label-secondary"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
<div className="col-12 text-end">
<button
type="reset"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading? "Please Wait...":"Submit"}
</button>
</div>
</form>

View File

@ -6,7 +6,8 @@ import { MasterRespository } from '../../repositories/MastersRepository';
import { clearApiCacheKey } from '../../slices/apiCacheSlice';
import { getCachedData, cacheData } from '../../slices/apiDataManager';
import showToast from '../../services/toastService';
import { useCreateContactTag } from '../../hooks/masterHook/useMaster';
import {useCreateContactTag} from '../../hooks/masterHook/useMaster';
import Label from '../common/Label';
const schema = z.object({
@ -64,17 +65,17 @@ const CreateContactTag = ({ onClose }) => {
}, []);
return (<>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
<label className="form-label">Tag Name</label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">Description</label>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Tag Name</Label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>Description</Label>
<textarea
rows="3"
{...register("description")}
@ -92,21 +93,19 @@ const CreateContactTag = ({ onClose }) => {
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button" // not reset
className="btn btn-sm btn-label-secondary"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
<div className="col-12 text-end">
<button
type="reset"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading? "Please Wait...":"Submit"}
</button>
</div>
</form>

View File

@ -6,7 +6,8 @@ import { MasterRespository } from '../../repositories/MastersRepository';
import { clearApiCacheKey } from '../../slices/apiCacheSlice';
import { getCachedData, cacheData } from '../../slices/apiDataManager';
import showToast from '../../services/toastService';
import { useCreateJobRole } from '../../hooks/masterHook/useMaster';
import {useCreateJobRole} from '../../hooks/masterHook/useMaster';
import Label from '../common/Label';
const schema = z.object({
@ -91,16 +92,16 @@ const CreateJobRole = ({ onClose }) => {
{/* <div className="col-12 col-md-12">
<label className="fs-5 text-dark text-center d-flex align-items-center justify-content-center flex-wrap">Create Job Role</label>
</div> */}
<div className="col-12 col-md-12">
<label className="form-label">Role</label>
<input type="text"
{...register("role")}
className={`form-control ${errors.role ? 'is-invalids' : ''}`}
/>
{errors.role && <p className="text-danger">{errors.role.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">Description</label>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Role</Label>
<input type="text"
{...register("role")}
className={`form-control ${errors.role ? 'is-invalids' : ''}`}
/>
{errors.role && <p className="text-danger">{errors.role.message}</p>}
</div>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>Description</Label>
<textarea
rows="3"
{...register("description")}
@ -118,21 +119,19 @@ const CreateJobRole = ({ onClose }) => {
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button" // change from reset button
className="btn btn-sm btn-label-secondary"
onClick={() => {
resetForm(); // optional: clears form
onClose?.(); // close modal via parent
}}
<div className="col-12 text-end">
<button
type="reset"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading? "Please Wait...":"Submit"}
</button>
</div>
</form>

View File

@ -8,6 +8,7 @@ import { MasterRespository } from "../../repositories/MastersRepository";
import { cacheData, getCachedData } from "../../slices/apiDataManager";
import showToast from "../../services/toastService";
import { useCreateApplicationRole } from "../../hooks/masterHook/useMaster";
import Label from "../common/Label";
const schema = z.object({
role: z.string().min(1, { message: "Role is required" }),
@ -109,8 +110,8 @@ const CreateRole = ({ modalType, onClose }) => {
<label className="fs-5 text-dark text-center d-flex align-items-center justify-content-center flex-wrap">Create Application Role</label>
</div> */}
<div className="col-12 col-md-12">
<label className="form-label">Role</label>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Role</Label>
<input
type="text"
{...register("role")}
@ -119,10 +120,10 @@ const CreateRole = ({ modalType, onClose }) => {
{errors.role && <p className="text-danger">{errors.role.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>
Description
</label>
</Label>
<textarea
rows="3"
{...register("description")}
@ -228,18 +229,19 @@ const CreateRole = ({ modalType, onClose }) => {
{masterFeatures && (
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button"
className="btn btn-sm btn-label-secondary"
onClick={onClose}
<div className="col-12 text-end">
<button
type="reset"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading ? "Please Wait..." : "Submit"}
</button>
</div>
)}
</form>

View File

@ -6,7 +6,8 @@ import { MasterRespository } from '../../repositories/MastersRepository';
import { clearApiCacheKey } from '../../slices/apiCacheSlice';
import { getCachedData, cacheData } from '../../slices/apiDataManager';
import showToast from '../../services/toastService';
import { useCreateWorkCategory } from '../../hooks/masterHook/useMaster';
import {useCreateWorkCategory} from '../../hooks/masterHook/useMaster';
import Label from '../common/Label';
const schema = z.object({
@ -76,21 +77,21 @@ const CreateWorkCategory = ({ onClose }) => {
}, []);
return (<>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
{/* <div className="col-12 col-md-12">
<label className="fs-5 text-dark text-center d-flex align-items-center justify-content-center flex-wrap">Create Work Category</label>
<label className="fs-5 text-dark text-center d-flex align-items-center justify-content-center flex-wrap">Create Work Category</label>
</div> */}
<div className="col-12 col-md-12">
<label className="form-label">Category Name</label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">Description</label>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Category Name</Label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>Description</Label>
<textarea
rows="3"
{...register("description")}
@ -108,20 +109,19 @@ const CreateWorkCategory = ({ onClose }) => {
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button" // not reset
className="btn btn-sm btn-label-secondary"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
<div className="col-12 text-end">
<button
type="reset"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading? "Please Wait...":"Submit"}
</button>
</div>
</form>

View File

@ -2,10 +2,11 @@ import React, { useEffect, useState } from "react";
import { useForm, useFieldArray } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import {MasterRespository} from "../../repositories/MastersRepository";
import { MasterRespository } from "../../repositories/MastersRepository";
import showToast from "../../services/toastService";
import {getCachedData,cacheData} from "../../slices/apiDataManager";
import {useUpdateActivity} from "../../hooks/masterHook/useMaster";
import { getCachedData, cacheData } from "../../slices/apiDataManager";
import { useUpdateActivity } from "../../hooks/masterHook/useMaster";
import Label from "../common/Label";
const schema = z.object({
@ -26,88 +27,88 @@ const schema = z.object({
const UpdateActivity = ({ activityData, onClose }) => {
const { mutate: updateActivity, isPending: isLoading } = useUpdateActivity(() => onClose?.());
const {
register,
handleSubmit,
control,
setValue,
reset,
setError,
clearErrors,
getValues,
formState: { errors },
} = useForm({
resolver: zodResolver(schema),
defaultValues: {
id: activityData?.id,
activityName: activityData?.activityName,
unitOfMeasurement: activityData?.unitOfMeasurement,
checkList: activityData?.checkLists || [],
},
});
const {
register,
handleSubmit,
control,
setValue,
reset,
setError,
clearErrors,
getValues,
formState: { errors },
} = useForm({
resolver: zodResolver(schema),
defaultValues: {
id: activityData?.id,
activityName: activityData?.activityName,
unitOfMeasurement: activityData?.unitOfMeasurement,
checkList: activityData?.checkLists || [],
},
});
const { fields: checkListItems, append, remove } = useFieldArray({
control,
name: "checkList",
});
const { fields: checkListItems, append, remove } = useFieldArray({
control,
name: "checkList",
});
useEffect(() => {
if (activityData) {
reset({
id: activityData.id,
activityName: activityData.activityName,
unitOfMeasurement: activityData.unitOfMeasurement,
checkList: activityData.checkLists || [],
});
}
}, [activityData, reset]);
useEffect(() => {
if (activityData) {
reset({
id: activityData.id,
activityName: activityData.activityName,
unitOfMeasurement: activityData.unitOfMeasurement,
checkList: activityData.checkLists || [],
});
}
}, [activityData, reset]);
const addChecklistItem = () => {
const values = getValues("checkList");
const lastIndex = checkListItems.length - 1;
const addChecklistItem = () => {
const values = getValues("checkList");
const lastIndex = checkListItems.length - 1;
if (
checkListItems.length > 0 &&
(!values?.[lastIndex] || values[lastIndex].description.trim() === "")
) {
setError(`checkList.${lastIndex}.description`, {
type: "manual",
message: "Please fill this checklist item before adding another.",
});
return;
}
if (
checkListItems.length > 0 &&
(!values?.[lastIndex] || values[lastIndex].description.trim() === "")
) {
setError(`checkList.${lastIndex}.description`, {
type: "manual",
message: "Please fill this checklist item before adding another.",
});
return;
}
clearErrors(`checkList.${lastIndex}.description`);
append({ id: null, description: "", isMandatory: false });
};
const removeChecklistItem = (index) => {
remove(index);
};
const handleChecklistChange = (index, value) => {
setValue(`checkList.${index}`, value);
};
const onSubmit = (formData) => {
const payload = { ...formData, id: activityData.id };
updateActivity({ id: activityData.id, payload });
clearErrors(`checkList.${lastIndex}.description`);
append({ id: null, description: "", isMandatory: false });
};
// const onSubmit = async(data) => {
const removeChecklistItem = (index) => {
remove(index);
};
const handleChecklistChange = (index, value) => {
setValue(`checkList.${index}`, value);
};
const onSubmit = (formData) => {
const payload = { ...formData, id: activityData.id };
updateActivity({ id: activityData.id, payload });
};
// const onSubmit = async(data) => {
// setIsLoading(true);
// const Activity = {...data, id:activityData.id}
// try
// {
// const response = await MasterRespository.updateActivity( activityData?.id, Activity );
// const updatedActivity = response.data;
// const cachedData = getCachedData("Activity")
// if (cachedData) {
// const updatedActivities = cachedData.map((activity) =>
// activity.id === updatedActivity.id ? { ...activity, ...updatedActivity } : activity
// );
// cacheData( "Activity", updatedActivities );
// onClose()
// }
@ -121,18 +122,18 @@ const onSubmit = (formData) => {
// }
// };
useEffect(() => {
const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el));
}, []);
useEffect(() => {
const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el));
}, []);
return (
<form onSubmit={handleSubmit(onSubmit)}>
{/* <h6>Update Activity</h6> */}
<div className="row">
{/* Activity Name */}
<div className="col-md-6">
<label className="form-label">Activity Name</label>
<div className="col-md-6 text-start">
<Label className="form-label" required>Activity Name</Label>
<input
type="text"
{...register("activityName")}
@ -144,8 +145,8 @@ useEffect(() => {
</div>
{/* Unit of Measurement */}
<div className="col-md-6">
<label className="form-label">Measurement</label>
<div className="col-md-6 text-start">
<Label className="form-label" required>Measurement</Label>
<input
type="text"
{...register("unitOfMeasurement")}
@ -160,93 +161,94 @@ useEffect(() => {
<div className="col-md-12 text-start mt-1">
<p className="py-1 my-0">{checkListItems.length > 0 ? "Check List" : "Add Check List"}</p>
{checkListItems.length > 0 && (
<table className="table mt-1 border-0">
<thead className="py-0 my-0 table-border-top-0">
<tr className="py-1">
<th colSpan={2} className="py-1">
<small>Name</small>
</th>
<th colSpan={2} className="py-1 text-center">
<small>Is Mandatory</small>
</th>
<th className="text-center py-1">Action</th>
</tr>
</thead>
<tbody>
{checkListItems.map((item, index) => (
<tr key={item.id} className="border-top-0">
<td colSpan={2} className=" border-0">
<input
className="d-none"
{...register(`checkList.${index}.id`)}
></input>
<input
{...register(`checkList.${index}.description`)}
className="form-control form-control-sm"
placeholder={`Checklist item ${index + 1}`}
onChange={(e) =>
handleChecklistChange(index, e.target.value)
}
/>
{errors.checkList?.[index]?.description && (
<small
style={{ fontSize: "10px" }}
className="danger-text"
>
{errors.checkList[index]?.description?.message}
</small>
)}
</td>
<td colSpan={2} className="text-center border-0">
<input
className="form-check-input"
type="checkbox"
{...register(`checkList.${index}.isMandatory`)}
defaultChecked={item.isMandatory}
/>
</td>
<td className="text-center border-0">
<button
type="button"
onClick={() => removeChecklistItem(index)}
className="btn btn-xs btn-icon btn-text-secondary"
>
<i className="bx bxs-minus-circle text-danger"data-bs-toggle="tooltip"
title="Add Check"
data-bs-original-title="Add check" ></i>
</button>
</td>
</tr>
))}
</tbody>
</table>
<table className="table mt-1 border-0">
<thead className="py-0 my-0 table-border-top-0">
<tr className="py-1">
<th colSpan={2} className="py-1">
<small>Name</small>
</th>
<th colSpan={2} className="py-1 text-center">
<small>Is Mandatory</small>
</th>
<th className="text-center py-1">Action</th>
</tr>
</thead>
<tbody>
{checkListItems.map((item, index) => (
<tr key={item.id} className="border-top-0">
<td colSpan={2} className=" border-0">
<input
className="d-none"
{...register(`checkList.${index}.id`)}
></input>
<input
{...register(`checkList.${index}.description`)}
className="form-control form-control-sm"
placeholder={`Checklist item ${index + 1}`}
onChange={(e) =>
handleChecklistChange(index, e.target.value)
}
/>
{errors.checkList?.[index]?.description && (
<small
style={{ fontSize: "10px" }}
className="danger-text"
>
{errors.checkList[index]?.description?.message}
</small>
)}
</td>
<td colSpan={2} className="text-center border-0">
<input
className="form-check-input"
type="checkbox"
{...register(`checkList.${index}.isMandatory`)}
defaultChecked={item.isMandatory}
/>
</td>
<td className="text-center border-0">
<button
type="button"
onClick={() => removeChecklistItem(index)}
className="btn btn-xs btn-icon btn-text-secondary"
>
<i className="bx bxs-minus-circle text-danger" data-bs-toggle="tooltip"
title="Add Check"
data-bs-original-title="Add check" ></i>
</button>
</td>
</tr>
))}
</tbody>
</table>
)}
<button
type="button"
type="button"
className="btn btn-xs btn-primary mt-2"
onClick={addChecklistItem}
>
<i className="bx bx-plus-circle" data-bs-toggle="tooltip"
title="Add Check"
data-bs-original-title="Add check" ></i>
<i className="bx bx-plus-circle" data-bs-toggle="tooltip"
title="Add Check"
data-bs-original-title="Add check" ></i>
</button>
</div>
{/* Submit / Cancel */}
<div className="col-12 text-center mt-3">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait" : "Submit"}
</button>
<div className="col-12 text-end mt-3">
<button
type="button" // change to button
className="btn btn-sm btn-label-secondary"
type="button"
className="btn btn-sm btn-label-secondary me-3"
onClick={onClose}
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading ? "Please Wait" : "Submit"}
</button>
</div>
</div>
</form>

View File

@ -6,7 +6,8 @@ import { MasterRespository } from '../../repositories/MastersRepository';
import { clearApiCacheKey } from '../../slices/apiCacheSlice';
import { getCachedData, cacheData } from '../../slices/apiDataManager';
import showToast from '../../services/toastService';
import { useUpdateContactCategory } from '../../hooks/masterHook/useMaster';
import {useUpdateContactCategory} from '../../hooks/masterHook/useMaster';
import Label from '../common/Label';
const schema = z.object({
@ -83,17 +84,17 @@ const EditContactCategory = ({ data, onClose }) => {
}, []);
return (<>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
<label className="form-label">Category Name</label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">Description</label>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Category Name</Label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>Description</Label>
<textarea
rows="3"
{...register("description")}
@ -111,20 +112,19 @@ const EditContactCategory = ({ data, onClose }) => {
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button" // not reset
className="btn btn-sm btn-label-secondary"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
<div className="col-12 text-end">
<button
type="button"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading? "Please Wait...":"Submit"}
</button>
</div>
</form>

View File

@ -6,7 +6,8 @@ import { MasterRespository } from '../../repositories/MastersRepository';
import { clearApiCacheKey } from '../../slices/apiCacheSlice';
import { getCachedData, cacheData } from '../../slices/apiDataManager';
import showToast from '../../services/toastService';
import { useUpdateContactTag } from '../../hooks/masterHook/useMaster';
import {useUpdateContactTag} from '../../hooks/masterHook/useMaster';
import Label from '../common/Label';
const schema = z.object({
@ -83,17 +84,17 @@ const EditContactTag = ({ data, onClose }) => {
}, []);
return (<>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
<label className="form-label">Tag Name</label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">Description</label>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Tag Name</Label>
<input type="text"
{...register("name")}
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
/>
{errors.name && <p className="text-danger">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>Description</Label>
<textarea
rows="3"
{...register("description")}
@ -111,20 +112,19 @@ const EditContactTag = ({ data, onClose }) => {
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button" // not reset
className="btn btn-sm btn-label-secondary"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
<div className="col-12 text-end">
<button
type="button"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary ">
{isLoading? "Please Wait...":"Submit"}
</button>
</div>
</form>

View File

@ -5,7 +5,8 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { MasterRespository } from '../../repositories/MastersRepository';
import { cacheData, getCachedData } from '../../slices/apiDataManager';
import showToast from '../../services/toastService';
import { useUpdateJobRole } from '../../hooks/masterHook/useMaster';
import {useUpdateJobRole} from '../../hooks/masterHook/useMaster';
import Label from '../common/Label';
@ -99,16 +100,16 @@ const EditJobRole = ({ data, onClose }) => {
{/* <div className="col-12 col-md-12">
<label className="fs-5 text-dark text-center d-flex align-items-center justify-content-center flex-wrap">Edit Job Role</label>
</div> */}
<div className="col-12 col-md-12">
<label className="form-label">Role</label>
<input type="text"
{...register("role")}
className={`form-control ${errors.role ? 'is-invalids' : ''}`}
/>
{errors.role && <p className="text-danger">{errors.role.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">Description</label>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Role</Label>
<input type="text"
{...register("role")}
className={`form-control ${errors.role ? 'is-invalids' : ''}`}
/>
{errors.role && <p className="text-danger">{errors.role.message}</p>}
</div>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>Description</Label>
<textarea
rows="3"
{...register("description")}
@ -127,17 +128,19 @@ const EditJobRole = ({ data, onClose }) => {
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
<div className="col-12 text-end">
<button
type="button"
className="btn btn-sm btn-label-secondary"
onClick={onClose} // 👈 This will now close the popup
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading? "Please Wait...":"Submit"}
</button>
</div>

View File

@ -8,6 +8,7 @@ import { MasterRespository } from "../../repositories/MastersRepository";
import { cacheData, getCachedData } from "../../slices/apiDataManager";
import showToast from "../../services/toastService";
import { useUpdateApplicationRole } from "../../hooks/masterHook/useMaster";
import Label from "../common/Label";
const updateSchema = z.object({
role: z.string().min(1, { message: "Role is required" }),
@ -162,8 +163,8 @@ const EditMaster = ({ master, onClose }) => {
return (
<form className="row g-2 " onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
<label className="form-label">Role</label>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Role</Label>
<input type="text"
{...register("role")}
className={`form-control ${errors.role ? 'is-invalid' : ''}`}
@ -171,8 +172,8 @@ const EditMaster = ({ master, onClose }) => {
{errors.role && <p className="text-danger">{errors.role.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">Description</label>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>Description</Label>
<textarea
rows="3"
{...register("description")}
@ -275,15 +276,17 @@ const EditMaster = ({ master, onClose }) => {
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3"> {isLoading ? "Please Wait..." : "Submit"}</button>
<div className="col-12 text-end mt-3">
<button
type="button"
className="btn btn-sm btn-label-secondary"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
onClick={onClose}
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary"> {isLoading ? "Please Wait..." : "Submit"}</button>
</div>

View File

@ -116,17 +116,18 @@ const EditWorkCategory = ({ data, onClose }) => {
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait..." : "Submit"}
</button>
<div className="col-12 text-center mt-3">
<button
type="button"
className="btn btn-sm btn-label-secondary"
className="btn btn-sm btn-label-secondary me-3"
onClick={onClose}
>
Cancel
</button>
<button type="submit" className="btn btn-sm btn-primary">
{isLoading ? "Please Wait..." : "Submit"}
</button>
</div>

View File

@ -6,6 +6,7 @@ import {
useCreateExpenseType,
useUpdateExpenseType,
} from "../../hooks/masterHook/useMaster";
import Label from "../common/Label";
const ExpnseSchema = z.object({
name: z.string().min(1, { message: "Name is required" }),
@ -52,8 +53,8 @@ const ManageExpenseType = ({ data = null, onClose }) => {
}, [data]);
return (
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
<label className="form-label">Expesne Type Name</label>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Expesne Type Name</Label>
<input
type="text"
{...register("name")}
@ -61,10 +62,10 @@ const ManageExpenseType = ({ data = null, onClose }) => {
/>
{errors.name && <p className="danger-text">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>
Description
</label>
</Label>
<textarea
rows="3"
{...register("description")}
@ -83,10 +84,20 @@ const ManageExpenseType = ({ data = null, onClose }) => {
{...register("noOfPersonsRequired")}
/>
</div>
<div className="col-12 text-center">
<div className="col-12 text-end">
<button
type="reset"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
disabled={isPending || isPendingUpdate}
onClick={()=>onClose()}
>
Cancel
</button>
<button
type="submit"
className="btn btn-sm btn-primary me-3"
className="btn btn-sm btn-primary"
disabled={isPending || isPendingUpdate}
>
{isPending || isPendingUpdate
@ -95,16 +106,7 @@ const ManageExpenseType = ({ data = null, onClose }) => {
? "Update"
: "Submit"}
</button>
<button
type="reset"
className="btn btn-sm btn-label-secondary "
data-bs-dismiss="modal"
aria-label="Close"
disabled={isPending || isPendingUpdate}
onClick={()=>onClose()}
>
Cancel
</button>
</div>
</form>
);

View File

@ -3,6 +3,7 @@ import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useCreatePaymentMode, useUpdatePaymentMode } from "../../hooks/masterHook/useMaster";
import Label from "../common/Label";
const ExpnseSchema = z.object({
name: z.string().min(1, { message: "Name is required" }),
@ -46,8 +47,8 @@ const ManagePaymentMode = ({ data = null, onClose }) => {
return (
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
<label className="form-label">Payment Mode Name</label>
<div className="col-12 col-md-12 text-start">
<Label className="form-label" required>Payment Mode Name</Label>
<input
type="text"
{...register("name")}
@ -55,10 +56,10 @@ const ManagePaymentMode = ({ data = null, onClose }) => {
/>
{errors.name && <p className="danger-text">{errors.name.message}</p>}
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="description">
<div className="col-12 col-md-12 text-start">
<Label className="form-label" htmlFor="description" required>
Description
</label>
</Label>
<textarea
rows="3"
{...register("description")}
@ -70,23 +71,24 @@ const ManagePaymentMode = ({ data = null, onClose }) => {
)}
</div>
<div className="col-12 text-center">
<div className="col-12 text-end">
<button
type="submit"
className="btn btn-sm btn-primary me-3"
disabled={isPending || Updating}
>
{isPending || Updating ? "Please Wait..." : Updating ? "Update" : "Submit"}
</button>
<button
type="button"
className="btn btn-sm btn-label-secondary"
onClick={onClose} // call onClose here
type="reset"
className="btn btn-sm btn-label-secondary me-3"
data-bs-dismiss="modal"
aria-label="Close"
disabled={isPending || Updating}
>
Cancel
</button>
<button
type="submit"
className="btn btn-sm btn-primary"
disabled={isPending || Updating}
>
{isPending || Updating ? "Please Wait..." : Updating ? "Update" : "Submit"}
</button>
</div>
</form>
);

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from "react";
import React, { useState, useEffect } from "react";
import {
cacheData,
clearCacheKey,
@ -26,7 +26,7 @@ import { useQueryClient } from "@tanstack/react-query";
const AttendancePage = () => {
const [activeTab, setActiveTab] = useState("all");
const [ShowPending, setShowPending] = useState(false);
const [searchTerm, setSearchTerm] = useState("");
const [searchTerm, setSearchTerm] = useState("");
const queryClient = useQueryClient();
const loginUser = getCachedProfileData();
@ -117,60 +117,70 @@ const AttendancePage = () => {
{ label: "Attendance", link: null },
]}
></Breadcrumb>
<div className="nav-align-top nav-tabs-shadow" >
<ul className="nav nav-tabs" role="tablist">
<li className="nav-item">
<button
type="button"
<div className="nav-align-top nav-tabs-shadow">
{/* Tabs */}
<div className="nav-align-top nav-tabs-shadow bg-white border-bottom">
<div className="row align-items-center g-0 mb-3 mb-md-0">
{/* Tabs */}
<div className="col-12 col-md">
<ul className="nav nav-tabs" role="tablist">
<li className="nav-item">
<button
type="button"
className={`nav-link ${
activeTab === "all" ? "active" : ""
} fs-6`}
onClick={() => handleTabChange("all")}
data-bs-toggle="tab"
data-bs-target="#navs-top-home"
>
Today's
</button>
</li>
<li className="nav-item">
<button
type="button"
onClick={() => handleTabChange("all")}
data-bs-toggle="tab"
data-bs-target="#navs-top-home"
>
Today's
</button>
</li>
<li className="nav-item">
<button
type="button"
className={`nav-link ${
activeTab === "logs" ? "active" : ""
} fs-6`}
onClick={() => handleTabChange("logs")}
data-bs-toggle="tab"
data-bs-target="#navs-top-profile"
>
Logs
</button>
</li>
<li className={`nav-item ${!DoRegularized && "d-none"}`}>
<button
type="button"
onClick={() => handleTabChange("logs")}
data-bs-toggle="tab"
data-bs-target="#navs-top-profile"
>
Logs
</button>
</li>
<li className={`nav-item ${!DoRegularized ? "d-none" : ""}`}>
<button
type="button"
className={`nav-link ${
activeTab === "regularization" ? "active" : ""
} fs-6`}
onClick={() => handleTabChange("regularization")}
data-bs-toggle="tab"
data-bs-target="#navs-top-messages"
>
Regularization
</button>
</li>
onClick={() => handleTabChange("regularization")}
data-bs-toggle="tab"
data-bs-target="#navs-top-messages"
>
Regularization
</button>
</li>
</ul>
</div>
{/* 🔹 Search box placed after Regularization tab */}
<li className="nav-item ms-auto me-3">
<input
type="text"
className="form-control form-control-sm mt-1"
placeholder="Search Employee..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{ minWidth: "200px" }}
/>
</li>
</ul>
{/* Single search input that moves */}
<div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto px-2">
<input
type="text"
className="form-control form-control-sm"
placeholder="Search Employee..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{ minWidth: "200px" }}
/>
</div>
</div>
</div>
<div className="tab-content attedanceTabs py-0 px-1 px-sm-3">
{selectedProject ? (

View File

@ -173,12 +173,12 @@ const DailyTask = () => {
currentSelectedBuilding={filters.selectedBuilding}
currentSelectedFloors={filters.selectedFloors}
currentSelectedActivities={filters.selectedActivities}
selectedProject={selectedProject}
selectedProject={selectedProject}
/>
</div>
{/* --- Table --- */}
<div className="table-responsive text-nowrap mt-3">
<div className="table-responsive text-nowrap mt-3" style={{ minHeight: "200px" }}>
<table className="table">
<thead>
<tr>
@ -193,14 +193,16 @@ const DailyTask = () => {
<tbody>
{taskLoading && (
<tr>
<td colSpan={6} className="text-center">
<Loader/>
<td colSpan={6} className="text-center align-middle" style={{ height: "200px" }}>
<Loader />
</td>
</tr>
)}
{!taskLoading && groupedTasks.length === 0 && (
<tr>
<td colSpan={6} className="text-center">No Reports Found</td>
<td colSpan={6} className="text-center align-middle" style={{ height: "200px" }}>
No Reports Found
</td>
</tr>
)}
{!taskLoading &&
@ -211,7 +213,7 @@ const DailyTask = () => {
</tr>
{tasks.map((task, idx) => (
<tr key={task.id || idx}>
<td className="flex-wrap text-start">
<td className="flex-wrap text-start">
<div>{task.workItem.activityMaster?.activityName || "No Activity Name"}</div>
<div className="text-sm">
{task.workItem.workArea?.floor?.building?.name} {task.workItem.workArea?.floor?.floorName} {task.workItem.workArea?.areaName}
@ -239,6 +241,7 @@ const DailyTask = () => {
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@ -414,14 +414,11 @@ const EmployeeList = () => {
{/* Add Employee Button */}
{Manage_Employee && (
<button
className="btn btn-sm btn-primary"
className="p-1 me-1 m-sm-0 bg-primary rounded-circle"
type="button"
onClick={() => handleEmployeeModel(null)}
>
<i className="bx bx-plus-circle me-2"></i>
<span className="d-none d-md-inline-block">
Add New Employee
</span>
<i className="bx bx-plus fs-4 text-white"></i>
</button>
)}
</div>
@ -636,7 +633,7 @@ const EmployeeList = () => {
}
className="dropdown-item py-1"
>
<i className="bx bx-detail bx-sm"></i> View
<i className="bx bx-show text-primary bx-sm"></i> View
</button>
{/* If ACTIVE employee */}
@ -648,8 +645,7 @@ const EmployeeList = () => {
handleEmployeeModel(item.id)
}
>
<i className="bx bx-edit bx-sm"></i>{" "}
Edit
<i className="bx bx-edit text-secondary bx-sm"></i> Edit
</button>
{/* Suspend only when active */}
@ -658,8 +654,7 @@ const EmployeeList = () => {
className="dropdown-item py-1"
onClick={() => handleOpenDelete(item)}
>
<i className="bx bx-task-x bx-sm"></i>{" "}
Suspend
<i className="bx bx-task-x text-danger bx-sm"></i> Suspend
</button>
)}
@ -684,8 +679,7 @@ const EmployeeList = () => {
className="dropdown-item py-1"
onClick={() => handleOpenDelete(item)}
>
<i className="bx bx-refresh bx-sm me-1"></i>{" "}
Re-activate
<i className="bx bx-refresh text-danger bx-sm me-0"></i> Re-activate
</button>
)}
</div>

View File

@ -163,7 +163,7 @@ useEffect(() => {
name="DataTables_Table_0_length"
aria-controls="DataTables_Table_0"
className="form-select py-1 px-2"
style={{ fontSize: "0.875rem", height: "32px", width: "150px" }}
style={{ fontSize: "0.875rem", height: "32px", width: "170px" }}
value={selectedMaster}
>
{isLoading && (

View File

@ -83,7 +83,7 @@ const ProjectDetails = () => {
return (
<>
<div className="row">
<div className="col-lg-4 col-md-5 mt-5">
<div className="col-lg-4 col-md-5 mt-2">
<AboutProject></AboutProject>
<ProjectOverview project={projectId} />
</div>