Compare commits

..

No commits in common. "30a990849999ebaa0738f407eb2f089f63413dd9" and "a39002ccf33ecd4aadc4ef090ccdb3e576bf2e70" have entirely different histories.

16 changed files with 351 additions and 459 deletions

View File

@ -13,7 +13,7 @@ export const ReportTask = ({ report, closeModal, refetch }) => {
completedTask: z completedTask: z
.number() .number()
.min(1, "Completed Work must be at least 1") .min(1, "Completed Work must be at least 1")
.int("Completed Work must be an integer") .int("Completed Work must be an integer")
.positive("Completed Work must be a positive number") .positive("Completed Work must be a positive number")
.optional(), .optional(),
@ -63,65 +63,78 @@ export const ReportTask = ({ report, closeModal, refetch }) => {
></button> ></button>
<div className="container m-0"> <div className="container m-0">
<div class="mb-1 row text-start"> <div className="d-flex justify-content-between">
<label for="html5-text-input" class="col-md-4 col-form-label"> <figure className="text-start p-0 m-0">
Assigned Date :{" "} <blockquote className="blockquote">
</label> <small>
<div class="col-md-8 text-start"> {" "}
<label class="col-md-2 col-form-label"> Assigned Date : {formatDate(report?.assignmentDate)}
{formatDate(report?.assignmentDate)} </small>
</label> </blockquote>
</div> </figure>
<figure className="text-end p-0 m-0">
<blockquote className="blockquote">
<small>Assigned By</small>
</blockquote>
<figcaption className="blockquote-footer mb-0">
{/* <div className="d-flex avatar avatar-xs">
<span className="avatar-initial rounded-circle bg-label-primary">
{report?.assignedBy?.firstName.slice(0, 1)}
</span> */}
<cite title="Source Title m-0">{` ${report?.assignedBy.firstName} ${report?.assignedBy.lastName}`}</cite>
{/* </div> */}
</figcaption>
</figure>
</div> </div>
<div class="mb-1 row text-start">
<label for="html5-search-input" class="col-md-4 col-form-label"> <div className="d-flex p-0 m-0">
Assigned By :{" "} <div className="flex-shrink-0 mt-1 mx-sm-0 px-2 mx-auto">
</label> <i className="bx bx-buildings"></i>
<div class="col-md-8 text-start">
<label class=" col-form-label">{` ${report?.assignedBy.firstName} ${report?.assignedBy.lastName}`}</label>
</div>
</div>
<div class="mb-1 row text-start">
<label for="html5-email-input" class="col-md-4 col-form-label">
Wrok Area :
</label>
<div class="col-md-8 text-start text-wrap">
<label class=" col-form-label">
{" "}
{report?.workItem?.workArea?.floor?.building?.name}{" "}
<i class="bx bx-chevron-right"></i>{" "}
{report?.workItem?.workArea?.floor?.floorName}{" "}
<i class="bx bx-chevron-right"> </i>
{report?.workItem?.workArea?.areaName}
</label>
</div>
</div>
<div class="mb-1 row text-start">
<label for="html5-email-input" class="col-md-4 col-form-label">
Activity :
</label>
<div class="col-md-8 text-start text-wrap">
<label class=" col-form-label">
{report?.workItem?.activityMaster.activityName}
</label>
</div>
</div>
<div class="mb-1 row text-start">
<label for="html5-email-input" class="col-md-4 col-form-label">
Team Size :
</label>
<div class="col-md-8 text-start text-wrap">
<label class=" col-form-label">
{report?.teamMembers?.length}
</label>
</div> </div>
<p className="lead">
{report?.workItem?.workArea?.floor?.building?.name}
</p>
<p className="lead ms-12">
{report?.workItem?.workArea?.floor?.floorName}
</p>
</div> </div>
<dl className="row text-start ms-3">
<dt className="col-sm-6">
Work Area : {report?.workItem?.workArea?.areaName}
</dt>
<dd className="col-sm-6">
<small> {report?.workItem?.activityMaster.activityName}</small>
</dd>
</dl>
<dl className="row text-start ms-3">
<dt className="col-sm-4">Team</dt>
<dd className="col-sm-4 d-flex align-items-center avatar-group justify-content-start">
{report?.teamMembers.map((member) => (
<>
<div
data-bs-toggle="tooltip"
data-bs-html="true"
data-popup="tooltip-custom"
data-bs-placement="top"
title={`${member.firstName} ${member.lastName}`}
className="avatar avatar-xs"
>
{/* <img src="..." alt="Avatar" className="rounded-circle pull-up" /> */}
<span className="avatar-initial rounded-circle bg-label-primary">
{member?.firstName.slice(0, 1)}
</span>
</div>
</>
))}
</dd>
<dt className="col-sm-4 text-start">
Planned : {report?.plannedTask}
</dt>
</dl>
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<div class="mb-1 row text-start"> <div className="row p-0">
<label for="html5-email-input" class="col-md-4 col-form-label"> <div className="col-4">
Completed Work
</label>
<div class="col-md-8 text-start text-wrap">
<input <input
{...register("completedTask", { valueAsNumber: true })} {...register("completedTask", { valueAsNumber: true })}
id="smallInput" id="smallInput"
@ -135,12 +148,7 @@ export const ReportTask = ({ report, closeModal, refetch }) => {
</div> </div>
)} )}
</div> </div>
</div> <div className="col-8">
<div class="mb-1 row text-start">
<label for="html5-email-input" class="col-md-4 col-form-label">
Comment
</label>
<div class="col-md-8 text-start text-wrap">
<textarea <textarea
{...register("comment")} {...register("comment")}
className="form-control" className="form-control"
@ -149,10 +157,11 @@ export const ReportTask = ({ report, closeModal, refetch }) => {
placeholder="Enter comment" placeholder="Enter comment"
/> />
{errors.comment && ( {errors.comment && (
<div className="danger-text">{errors.comment.message}</div> <div className="text-danger">{errors.comment.message}</div>
)} )}
</div> </div>
</div> </div>
<div className="col-12 text-center my-2"> <div className="col-12 text-center my-2">
<button type="submit" className="btn btn-sm btn-primary me-3"> <button type="submit" className="btn btn-sm btn-primary me-3">
{loading ? "Please wait" : "Submit Report"} {loading ? "Please wait" : "Submit Report"}

View File

@ -69,7 +69,7 @@ const Header = () =>
<a <a
aria-label="toggle for sidebar" aria-label="toggle for sidebar"
className="nav-item nav-link px-0 me-xl-4" className="nav-item nav-link px-0 me-xl-4"
href="#"
> >
<i className="bx bx-menu bx-sm"></i> <i className="bx bx-menu bx-sm"></i>
</a> </a>

View File

@ -160,14 +160,13 @@ const ProjectCard = ({ projectData }) => {
data-bs-toggle="dropdown" data-bs-toggle="dropdown"
aria-expanded="false" aria-expanded="false"
> >
<i className="bx bx-dots-vertical-rounded bx-sm text-muted" data-bs-toggle="tooltip" data-bs-offset="0,8" data-bs-placement="top" data-bs-custom-class="tooltip-dark" title="More Action"></i> <i className="bx bx-dots-vertical-rounded bx-sm text-muted"></i>
</button> </button>
<ul className="dropdown-menu dropdown-menu-end"> <ul className="dropdown-menu dropdown-menu-end">
<li> <li>
<a <a
aria-label="click to View details" aria-label="click to View details"
className="dropdown-item" className="dropdown-item"
onClick={handleViewProject} onClick={handleViewProject}
> >
<i className="bx bx-detail me-2"></i> <i className="bx bx-detail me-2"></i>

View File

@ -5,14 +5,16 @@ const DateRangePicker = ({ onRangeChange }) => {
const inputRef = useRef(null); const inputRef = useRef(null);
useEffect(() => { useEffect(() => {
const today = new Date(); const today = new Date();
const fifteenDaysAgo = new Date(); const fifteenDaysAgo = new Date();
fifteenDaysAgo.setDate(today.getDate() - 15); fifteenDaysAgo.setDate(today.getDate() - 15);
const fp = flatpickr(inputRef.current, { const fp = flatpickr(inputRef.current, {
mode: "range", mode: "range",
dateFormat: "Y-m-d", dateFormat: "Y-m-d",
defaultDate: [fifteenDaysAgo, today], defaultDate: [fifteenDaysAgo, today], // set default range
static: true, static: true,
clickOpens: true, clickOpens: true,
onChange: (selectedDates, dateStr) => { onChange: (selectedDates, dateStr) => {
@ -21,11 +23,6 @@ const DateRangePicker = ({ onRangeChange }) => {
}, },
}); });
onRangeChange?.({
startDate: fifteenDaysAgo.toISOString().split("T")[0],
endDate: today.toISOString().split("T")[0],
});
return () => { return () => {
fp.destroy(); fp.destroy();
}; };

View File

@ -1,30 +1,26 @@
import React, { useState, useEffect } from "react"; import React,{useState,useEffect} from 'react'
import { useFieldArray, useForm } from "react-hook-form"; import {useFieldArray, useForm } from 'react-hook-form';
import { z } from "zod"; import { z } from 'zod';
import { zodResolver } from "@hookform/resolvers/zod"; import {zodResolver} from '@hookform/resolvers/zod';
import { MasterRespository } from "../../repositories/MastersRepository"; import { MasterRespository } from '../../repositories/MastersRepository';
import { clearApiCacheKey } from "../../slices/apiCacheSlice"; import { clearApiCacheKey } from '../../slices/apiCacheSlice';
import { getCachedData, cacheData } from "../../slices/apiDataManager"; import { getCachedData,cacheData } from '../../slices/apiDataManager';
import showToast from "../../services/toastService"; import showToast from '../../services/toastService';
const schema = z.object({ const schema = z.object({
activityName: z.string().min(1, { message: "Activity Name is required" }), activityName: z.string().min(1, { message: "Role is required" }),
unitOfMeasurement: z.string().min(1, { message: "Unit of Measurement is required" }), unitOfMeasurement: z.string().min(1, { message: "Description is required" }),
checkList: z checkList: z
.array( .array(z.string().min(1, { message: "Checklist item cannot be empty" }))
z.object({ .optional(),
check: z.string().min(1, { message: "Checklist item cannot be empty" }), });
isMandatory: z.boolean().default(false),
id: z.any().default(0), const CreateActivity = ({onClose}) =>
}) {
)
.optional(),
});
const CreateActivity = ({ onClose }) => {
const [isLoading, setIsLoading] = useState(false);
const [ isLoading, setIsLoading ] = useState( false )
const { const {
register, register,
handleSubmit, handleSubmit,
@ -38,197 +34,147 @@ const CreateActivity = ({ onClose }) => {
} = useForm({ } = useForm({
resolver: zodResolver(schema), resolver: zodResolver(schema),
defaultValues: { defaultValues: {
activityName: "", activityName: '',
unitOfMeasurement: "", unitOfMeasurement: '',
checkList: [], checkList: [],
}, },
}); });
// Setting up field array for checkList (dynamic fields)
const { const {
fields: checkListItems, fields: checkListItems,
append, append,
remove, remove,
} = useFieldArray({ } = useFieldArray({
control, control,
name: "checkList", name: 'checkList',
}); });
// Form submission handler // Form submission handler
const onSubmit = (data) => { const onSubmit = ( data ) =>
console.log(data); {
setIsLoading(true); console.log(data)
setIsLoading(true)
MasterRespository.updateActivity(data).then((resp)=>{
setIsLoading(false)
const cachedData = getCachedData("Activity");
const updatedData = [...cachedData, resp?.data];
cacheData("Activity", updatedData);
showToast("Activity Added successfully.", "success");
MasterRespository.createActivity(data) onClose()
.then( ( resp ) => }).catch((error)=>{
{ showToast(error.message, "error");
setIsLoading(false)
const cachedData = getCachedData("Activity"); })
const updatedData = [ ...cachedData, resp?.data ];
cacheData("Activity", updatedData);
showToast("Activity Successfully Added.", "success");
setIsLoading(false);
handleClose()
})
.catch((error) => {
showToast(error.message, "error");
setIsLoading(false);
});
}; };
// Add a new checklist item
const addChecklistItem = () => { const addChecklistItem = () => {
const values = getValues("checkList"); const values = getValues('checkList');
const lastIndex = checkListItems.length - 1; const lastIndex = checkListItems.length - 1;
if (
checkListItems.length > 0 &&
(!values?.[lastIndex] || values[lastIndex].check.trim() === "") if (checkListItems.length > 0 && (!values?.[lastIndex] || values[lastIndex].trim() === '')) {
) { setError(`checkList.${lastIndex}`, {
setError(`checkList.${lastIndex}.check`, { type: 'manual',
type: "manual", message: 'Please fill this checklist item before adding another.',
message: "Please fill this checklist item before adding another.",
}); });
return; return;
} }
clearErrors(`checkList.${lastIndex}.check`);
append({ clearErrors(`checkList.${lastIndex}`); // Clear the error if the input is filled.
id: 0, append(''); // Add a new empty checklist input
check: "",
isMandatory: false,
});
}; };
const removeChecklistItem = (index) => { const removeChecklistItem = (index) => {
remove(index); remove(index);
}; };
// Handle checklist item input change
const handleChecklistChange = (index, value) => { const handleChecklistChange = (index, value) => {
setValue(`checkList.${index}`, value); setValue(`checkList.${index}`, value);
}; };
const handleClose = () => { const handleClose = () =>
reset(); {
onClose(); reset()
}; onClose()
}
return ( return (
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<h6>Create Activity</h6> <div className="row">
<div className="row"> <div className="col-6">
<div className="col-6"> <label className="form-label">Activity</label>
<label className="form-label">Activity</label> <input
<input type="text"
type="text" {...register('activityName')}
{...register("activityName")} className={`form-control form-control-sm ${errors.activityName ? 'is-invalid' : ''}`}
className={`form-control form-control-sm ${ />
errors.activityName ? "is-invalid" : "" {errors.activityName && <p className="danger-text">{errors.activityName.message}</p>}
}`}
/>
{errors.activityName && (
<p className="danger-text">{errors.activityName.message}</p>
)}
</div>
<div className="col-6">
<label className="form-label">Measurement</label>
<input
type="text"
{...register("unitOfMeasurement")}
className={`form-control form-control-sm ${
errors.unitOfMeasurement ? "is-invalid" : ""
}`}
/>
{errors.unitOfMeasurement && (
<p className="danger-text">{errors.unitOfMeasurement.message}</p>
)}
</div>
<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 className="table-border-bottom-0 ">
{checkListItems.map((item, index) => (
<tr key={index} className="border-top-0">
<td colSpan={2} className="border-top-0 border-0">
<input
className="d-none"
{...register(`checkList.${index}.id`)}
></input>
<input
{...register(`checkList.${index}.check`)}
className="form-control form-control-sm"
placeholder={`Checklist item ${index + 1}`}
onChange={(e) =>
handleChecklistChange(index, e.target.value)
}
/>
{errors.checkList?.[index]?.check && (
<small
style={{ fontSize: "10px" }}
className="danger-text"
>
{errors.checkList[index]?.check?.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 class="bx bxs-minus-circle text-danger"></i>
</button>
</td>
</tr>
))}
</tbody>
</table>
)}
<button
type="button"
className="btn btn-xs btn-primary mt-2"
onClick={addChecklistItem}
>
<i class="bx bx-plus-circle"></i>
</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>
<button
type="reset"
className="btn btn-sm btn-label-secondary"
onClick={handleClose}
>
Cancel
</button>
</div>
</div> </div>
</form>
);
};
export default CreateActivity; <div className="col-6">
<label className="form-label">Measurement</label>
<input
type="text"
{...register('unitOfMeasurement')}
className={`form-control form-control-sm ${errors.unitOfMeasurement ? 'is-invalid' : ''}`}
/>
{errors.unitOfMeasurement && (
<p className="danger-text">{errors.unitOfMeasurement.message}</p>
)}
</div>
<div className="col-md-6 text-start">
{/* Dynamic checklist items */}
{checkListItems.map((item, index) => (
<div key={item.id} className=" align-items-center my-1">
<div className='d-flex align-items-center gap-2'>
<input
{...register(`checkList.${index}`)}
className="form-control form-control-sm"
placeholder={`Checklist item ${index + 1}`}
onChange={(e) => handleChecklistChange(index, e.target.value)} // Handle input change
/>
<button
type="button"
onClick={() => removeChecklistItem(index)} // Remove button
className="btn btn-xs btn-icon btn-text-secondary"
>
<span class='icon-base bx bx bx-x'></span>
</button>
</div>
{errors.checkList?.[index] && (
<p className="danger-text">{errors.checkList[index]?.message}</p>
)}
</div>
))}
{/* Add new checklist item */}
<button type="button" className="btn btn-sm btn-primary mt-2" onClick={addChecklistItem}>
+ Add Checklist Item
</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>
<button
type="reset"
className="btn btn-sm btn-label-secondary"
onClick={handleClose}
>
Cancel
</button>
</div>
</div>
</form>
)
}
export default CreateActivity

View File

@ -57,12 +57,15 @@ const onSubmit = (values) => {
}; };
MasterRespository.createRole(result).then((resp)=>{ MasterRespository.createRole(result).then((resp)=>{
console.log(resp)
setIsLoading(false) setIsLoading(false)
const cachedData = getCachedData( "Role" ); const cachedData = getCachedData( "Role" );
const updatedData = [...cachedData, resp.data]; console.log(cachedData)
const updatedData = [...cachedData, resp];
cacheData("Application Role", updatedData); cacheData("Role", updatedData);
showToast("Application Role Added successfully.", "success"); showToast("Role Added successfully.", "success");
onClose() onClose()
} ).catch( ( err ) => } ).catch( ( err ) =>
{ {

View File

@ -10,6 +10,7 @@ const DeleteMaster = ({ master, onClose }) => {
const index = mastersdata[master?.masterType]?.findIndex( const index = mastersdata[master?.masterType]?.findIndex(
(item) => String(item?.id) === String(master?.item?.id) (item) => String(item?.id) === String(master?.item?.id)
); );
console.log(index);
if (index !== -1) { if (index !== -1) {
mastersdata[master?.masterType].splice(index, 1); mastersdata[master?.masterType].splice(index, 1);
} }

View File

@ -1,28 +1,23 @@
import React, { useEffect, useState } from "react"; import React, { useState, useEffect } from 'react';
import { useForm, useFieldArray } from "react-hook-form"; import { useFieldArray, useForm } from 'react-hook-form';
import { z } from "zod"; import { z } from 'zod';
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from '@hookform/resolvers/zod';
import {MasterRespository} from "../../repositories/MastersRepository"; import {MasterRespository} from '../../repositories/MastersRepository';
import showToast from "../../services/toastService"; import axios from 'axios';
import {getCachedData,cacheData} from "../../slices/apiDataManager"; import showToast from '../../services/toastService';
import {cacheData, getCachedData} from '../../slices/apiDataManager';
// Zod Schema for validation
const schema = z.object({ const schema = z.object({
activityName: z.string().min(1, { message: "Activity name is required" }), activityName: z.string().min(1, { message: "Activity name is required" }),
unitOfMeasurement: z.string().min(1, { message: "Measurement is required" }), unitOfMeasurement: z.string().min(1, { message: "Measurement is required" }),
checkList: z checkList: z
.array( .array(z.string().min(1, { message: "Checklist item cannot be empty" }))
z.object({
id: z.any().default(0),
check: z.string().min(1, { message: "Checklist item cannot be empty" }),
isMandatory: z.boolean().default(false),
})
)
.optional(), .optional(),
}); } );
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOlsiOGFmNjFlNDgtYzRkMy00MTYzLWI4NjAtMmEyZWNiNjQ3NDZiIiwiYjUxMzcwOWEtYmZiZS00OTM1LTlmNWMtOGVjN2IwMzFjNTFlIl0sInN1YiI6InZpa2FzQG1hcmNvYWlvdC5jb20iLCJUZW5hbnRJZCI6IjIiLCJleHAiOjE3NDQzNzQyNzAsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTI0NiIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTI0NiJ9.reQlePmwDpBL-_mcGOrWwADLJrxmUse5Gd7A-OgDi9s"
const UpdateActivity = ({ activityData, onClose }) => { const EditActivity = ({activityData,onClose}) => {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const { const {
@ -30,212 +25,166 @@ const UpdateActivity = ({ activityData, onClose }) => {
handleSubmit, handleSubmit,
control, control,
setValue, setValue,
reset,
setError,
clearErrors, clearErrors,
setError,
getValues, getValues,
reset,
formState: { errors }, formState: { errors },
} = useForm({ } = useForm({
resolver: zodResolver(schema), resolver: zodResolver(schema),
defaultValues: { defaultValues: {
id:activityData.id, activityName: '',
activityName: activityData.activityName, unitOfMeasurement: '',
unitOfMeasurement: activityData.unitOfMeasurement, checkList: [],
checkLists: activityData.checkLists || [],
}, },
}); });
const { fields: checkListItems, append, remove } = useFieldArray({ // Setting up field array for checkList (dynamic fields)
const {
fields: checkListItems,
append,
remove,
} = useFieldArray({
control, control,
name: "checkList", name: 'checkList',
}); });
// Load initial data // Pre-populating the form with initial data when component mounts or initialData changes
useEffect(() => { useEffect(() => {
if (activityData) { if (activityData) {
reset( { reset({
id:activityData.id,
activityName: activityData.activityName, activityName: activityData.activityName,
unitOfMeasurement: activityData.unitOfMeasurement, unitOfMeasurement: activityData.unitOfMeasurement,
checkList: activityData.checkLists || [], checkList: activityData.checkList || [],
}); });
} }
}, [activityData]); }, [activityData, reset]);
// Form submission handler
const handleChecklistChange = (index, value) => { const onSubmit = async( data ) =>
setValue(`checkList.${index}`, value);
};
// Submit handler
const onSubmit = async(data) => {
setIsLoading(true);
const Activity = {...data, id:activityData.id}
try
{ {
const response = await MasterRespository.updateActivity( activityData?.id, Activity ); console.log(data)
const updatedActivity = response.data; setIsLoading(true)
const cachedData = getCachedData("Activity") MasterRespository.updateActivity(activityData?.id,data).then((resp)=>{
setIsLoading(false)
if (cachedData) { const cachedData = getCachedData("Activity");
const updatedActivities = cachedData.map((activity) => if (cachedData) {
activity.id === updatedActivity.id ? { ...activity, ...updatedActivity } : activity const updatedData = cachedData.map((activity) =>
); activity.id === activityData?.id
? {
cacheData( "Activity", updatedActivities ); ...activity,
activityName: resp.data.activityName,
unitOfMeasurement: resp.data.unitOfMeasurement,
}
: activity
);
cacheData("Activity", updatedData);
}
showToast("Activity Added successfully.", "success");
onClose() onClose()
} }).catch((error)=>{
setIsLoading( false ) showToast(error.message, "error");
showToast("Activity Successfully Updated", "success"); setIsLoading(false)
} catch ( err ) })
{
setIsLoading( false )
};
showToast("error.message", "error"); // Add a new checklist item
console.log(err)
}
};
// Add new checklist item
const addChecklistItem = () => { const addChecklistItem = () => {
const values = getValues("checkList"); const values = getValues('checkList');
const lastIndex = checkListItems.length - 1; const lastIndex = checkListItems.length - 1;
if ( // Prevent adding new input if the last one is empty
checkListItems.length > 0 && if (checkListItems.length > 0 && (!values?.[lastIndex] || values[lastIndex].trim() === '')) {
(!values?.[lastIndex] || values[lastIndex].check.trim() === "") setError(`checkList.${lastIndex}`, {
) { type: 'manual',
setError(`checkList.${lastIndex}.check`, { message: 'Please fill this checklist item before adding another.',
type: "manual",
message: "Please fill this checklist item before adding another.",
}); });
return; return;
} }
clearErrors(`checkList.${lastIndex}.check`); clearErrors(`checkList.${lastIndex}`); // Clear the error if the input is filled.
append({ id: 0, check: "", isMandatory: false }); append(''); // Add a new empty checklist input
}; };
// Remove a checklist item
const removeChecklistItem = (index) => { const removeChecklistItem = (index) => {
remove(index); remove(index); // Remove the checklist item from the field array
}; };
// Handle checklist item input change
const handleChecklistChange = (index, value) => {
setValue(`checkList.${index}`, value); // Update the value of the checklist item
};
const handleCLose = () =>
{
() => reset()
onClose()
}
return ( return (
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<h6>Update Activity</h6>
<div className="row"> <div className="row">
{/* Activity Name */} <div className="col-6">
<div className="col-md-6"> <label className="form-label">Activity</label>
<label className="form-label">Activity Name</label>
<input <input
type="text" type="text"
{...register("activityName")} {...register('activityName')}
className={`form-control form-control-sm ${errors.activityName ? "is-invalid" : ""}`} className={`form-control form-control-sm ${errors.activityName ? 'is-invalid' : ''}`}
/> />
{errors.activityName && ( {errors.activityName && <p className="danger-text">{errors.activityName.message}</p>}
<div className="text-danger">{errors.activityName.message}</div>
)}
</div> </div>
{/* Unit of Measurement */} <div className="col-6">
<div className="col-md-6"> <label className="form-label">Measurement</label>
<label className="form-label">Measurement</label>
<input <input
type="text" type="text"
{...register("unitOfMeasurement")} {...register('unitOfMeasurement')}
className={`form-control form-control-sm ${errors.unitOfMeasurement ? "is-invalid" : ""}`} className={`form-control form-control-sm ${errors.unitOfMeasurement ? 'is-invalid' : ''}`}
/> />
{errors.unitOfMeasurement && ( {errors.unitOfMeasurement && (
<div className="text-danger">{errors.unitOfMeasurement.message}</div> <p className="danger-text">{errors.unitOfMeasurement.message}</p>
)} )}
</div> </div>
{/* Checklist */} <div className="col-md-6 text-start">
<div className="col-md-12 text-start mt-1"> {/* Dynamic checklist items */}
<p className="py-1 my-0">{checkListItems.length > 0 ? "Check List" : "Add Check List"}</p> {checkListItems.map((item, index) => (
{checkListItems.length > 0 && ( <div key={item.id} className="d-flex align-items-center gap-2 my-1">
<table className="table mt-1 border-0"> <input
<thead className="py-0 my-0 table-border-top-0"> {...register(`checkList.${index}`)}
<tr className="py-1"> className="form-control form-control-sm"
<th colSpan={2} className="py-1"> placeholder={`Checklist item ${index + 1}`}
<small>Name</small> onChange={(e) => handleChecklistChange(index, e.target.value)} // Handle input change
</th> />
<th colSpan={2} className="py-1 text-center"> <button
<small>Is Mandatory</small> type="button"
</th> onClick={() => removeChecklistItem(index)} // Remove button
<th className="text-center py-1">Action</th> className="btn btn-xs btn-icon btn-text-secondary"
</tr> >
</thead> <span className="icon-base bx bx-x"/>
<tbody> </button>
{checkListItems.map((item, index) => ( {errors.checkList?.[index] && (
<tr key={item.id} className="border-top-0"> <p className="danger-text">{errors.checkList[index]?.message}</p>
<td colSpan={2} className=" border-0"> )}
<input </div>
className="d-none" ))}
{...register(`checkList.${index}.id`)} {/* Add new checklist item */}
></input> <button type="button" className="btn btn-sm btn-primary mt-2" onClick={addChecklistItem}>
<input + Add Checklist Item
{...register(`checkList.${index}.check`)}
className="form-control form-control-sm"
placeholder={`Checklist item ${index + 1}`}
onChange={(e) =>
handleChecklistChange(index, e.target.value)
}
/>
{errors.checkList?.[index]?.check && (
<small
style={{ fontSize: "10px" }}
className="danger-text"
>
{errors.checkList[index]?.check?.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 class="bx bxs-minus-circle text-danger"></i>
</button>
</td>
</tr>
))}
</tbody>
</table>
)}
<button
type="button"
className="btn btn-xs btn-primary mt-2"
onClick={addChecklistItem}
>
<i class="bx bx-plus-circle"></i>
</button> </button>
</div> </div>
{/* Submit / Cancel */}
<div className="col-12 text-center mt-3"> <div className="col-12 text-center mt-3">
<button type="submit" className="btn btn-sm btn-primary me-3"> <button type="submit" className="btn btn-sm btn-primary me-3">
{isLoading ? "Please Wait" : "Submit"} Submit
</button> </button>
<button <button
type="reset" type="reset"
className="btn btn-sm btn-label-secondary" className="btn btn-sm btn-label-secondary"
onClick={onClose} onClick={handleCLose}
> >
Cancel Cancel
</button> </button>
@ -245,4 +194,4 @@ const UpdateActivity = ({ activityData, onClose }) => {
); );
}; };
export default UpdateActivity; export default EditActivity;

View File

@ -101,7 +101,7 @@ const EditMaster=({master,onClose})=> {
setIsLoading( false ) setIsLoading( false )
const cachedData = getCachedData("Application Role"); const cachedData = getCachedData("Role");
if (cachedData) { if (cachedData) {
@ -109,9 +109,9 @@ const EditMaster=({master,onClose})=> {
role.id === resp.data?.id ? { ...role, ...resp.data } : role role.id === resp.data?.id ? { ...role, ...resp.data } : role
); );
cacheData("Application Role", updatedData); cacheData("Role", updatedData);
} }
showToast( "Application Role Updated successfully.", "success" ); showToast( "Role Update successfully.", "success" );
setIsLoading(false) setIsLoading(false)
onClose() onClose()
}).catch((Err)=>{ }).catch((Err)=>{

View File

@ -33,13 +33,13 @@ const MasterModal = ({ modaldata, closeModal }) => {
onClick={closeModal} onClick={closeModal}
></button> ></button>
<div className="text-center mb-2"></div> <div className="text-center mb-2"></div>
{modaldata?.modalType === "Application Role" && ( {modaldata?.modalType === "Role" && (
<CreateRole <CreateRole
masmodalType={modaldata.masterType} masmodalType={modaldata.masterType}
onClose={closeModal} onClose={closeModal}
/> />
)} )}
{modaldata?.modalType === "Edit-Application Role" && ( {modaldata?.modalType === "Edit-Role" && (
<EditRole master={modaldata} onClose={closeModal} /> <EditRole master={modaldata} onClose={closeModal} />
)} )}
{modaldata?.modalType === "delete" && ( {modaldata?.modalType === "delete" && (

View File

@ -1,6 +1,4 @@
// it important ------ export const mastersList = [{id:1, name: "Role"},{id:2, name: "Job Role"},{id:3,name:"Activity"}]
export const mastersList = [ {id: 1, name: "Application Role"}, {id: 2, name: "Job Role"}, {id: 3, name: "Activity"} ]
// -------------------
export const dailyTask = [ export const dailyTask = [
{ {

View File

@ -35,7 +35,7 @@ const useMaster = () => {
} else { } else {
let response; let response;
switch (selectedMaster) { switch (selectedMaster) {
case "Application Role": case "Role":
response = await MasterRespository.getRoles(); response = await MasterRespository.getRoles();
response = response.data; response = response.data;
break; break;

View File

@ -15,8 +15,8 @@ import DateRangePicker from "../../components/common/DateRangePicker";
import DatePicker from "../../components/common/DatePicker"; import DatePicker from "../../components/common/DatePicker";
const DailyTask = () => { const DailyTask = () => {
const { profile: LoggedUser } = useProfile(); const {profile: LoggedUser} = useProfile();
const { const {
projects, projects,
loading: project_lodaing, loading: project_lodaing,
@ -27,13 +27,13 @@ const DailyTask = () => {
); );
const dispatch = useDispatch(selectedProject); const dispatch = useDispatch(selectedProject);
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" }); const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
const { const {
TaskList, TaskList,
loading: task_loading, loading: task_loading,
error: task_error, error: task_error,
refetch, refetch,
} = useTaskList(selectedProject, dateRange.startDate, dateRange.endDate); } = useTaskList( selectedProject, dateRange.startDate, dateRange.endDate );
const [TaskLists, setTaskLists] = useState([]); const [TaskLists, setTaskLists] = useState([]);
@ -56,6 +56,7 @@ const DailyTask = () => {
selectTask(task); selectTask(task);
openModal(); openModal();
}; };
console.log(dateRange)
return ( return (
<> <>
@ -125,6 +126,7 @@ const DailyTask = () => {
))} ))}
</select> </select>
</div> </div>
</div> </div>
<div className="table-responsive text-nowrap"> <div className="table-responsive text-nowrap">
<table className="table"> <table className="table">
@ -189,7 +191,7 @@ const DailyTask = () => {
<td>{formatDate(task.assignmentDate)}</td> <td>{formatDate(task.assignmentDate)}</td>
<td className="text-center"> <td className="text-center">
<div className="d-flex align-items-center avatar-group justify-content-center"> <div className="d-flex align-items-center avatar-group justify-content-center">
{task.teamMembers.slice(0, 3).map((member) => ( {task.teamMembers.map((member) => (
<div <div
key={member.id} key={member.id}
data-bs-toggle="tooltip" data-bs-toggle="tooltip"
@ -205,27 +207,14 @@ const DailyTask = () => {
</span> </span>
</div> </div>
))} ))}
{task.teamMembers.length > 3 && (
<div
className="avatar avatar-xs"
data-bs-toggle="tooltip"
data-bs-placement="bottom"
title={`${task.teamMembers.length - 3} more`}
>
<span className="avatar-initial rounded-circle bg-label-secondary pull-up">
+{task.teamMembers.length - 3}
</span>
</div>
)}
</div> </div>
</td> </td>
<td className="text-center"> <td className="text-center">
<div className="d-flex justify-content-center"> <div className="d-flex justify-content-center">
<button <button
type="button" type="button"
className={`btn btn-xs btn-primary ${ className={`btn btn-xs btn-primary ${task.completedTask > 0 ? "d-none":""}`}
task.completedTask > 0 ? "d-none" : ""
}`}
onClick={() => { onClick={() => {
selectTask(task); selectTask(task);
openModal(); openModal();

View File

@ -36,8 +36,9 @@ const ForgotPasswordPage = () => {
const response = await AuthRepository.forgotPassword(data) const response = await AuthRepository.forgotPassword(data)
if ( response.data && response.success ) if ( response.data && response.success )
showToast( response.message, "success" ) showToast( response.message, "success" )
reset()
setLoading( false ) setLoading( false )
setEmail( "" )
console.log(response)
} catch ( err ) } catch ( err )
{ {

View File

@ -7,7 +7,7 @@ const MasterTable = ( {data, columns, loading, handleModalData} ) =>
{ {
const hasMasterPermission = useHasUserPermission(MANAGE_MASTER) const hasMasterPermission = useHasUserPermission(MANAGE_MASTER)
const selectedMaster = useSelector((store)=>store.localVariables.selectedMaster) const selectedMaster = useSelector((store)=>store.localVariables.selectedMaster)
const hiddenColumns = ["id", "featurePermission","tenant","tenantId","checkLists"]; const hiddenColumns = ["id", "featurePermission","tenant","tenantId"];
const safeData = Array.isArray(data) ? data : []; const safeData = Array.isArray(data) ? data : [];
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
@ -28,7 +28,7 @@ const MasterTable = ( {data, columns, loading, handleModalData} ) =>
.map((col) => ({ .map((col) => ({
...col, ...col,
label: label:
col.key === "role" || col.key === "activityName" || col.key === "status" ? "Name" : col.label, col.key === "role" || col.key === "Activity" || col.key === "status" ? "Name" : col.label,
})); }));
return ( return (
@ -45,7 +45,7 @@ const MasterTable = ( {data, columns, loading, handleModalData} ) =>
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th> Name</th> <th>{ selectedMaster} Name</th>
<th>{selectedMaster} {selectedMaster === "Activity" ? "Unit":"Description" }</th> <th>{selectedMaster} {selectedMaster === "Activity" ? "Unit":"Description" }</th>
<th className={` ${!hasMasterPermission && 'd-none'}`}>Actions</th> <th className={` ${!hasMasterPermission && 'd-none'}`}>Actions</th>
</tr> </tr>

View File

@ -3,7 +3,7 @@ import { createSlice } from "@reduxjs/toolkit";
const localVariablesSlice = createSlice({ const localVariablesSlice = createSlice({
name: "localVariables", name: "localVariables",
initialState: { initialState: {
selectedMaster:"Application Role", selectedMaster:"Role",
regularizationCount:0, regularizationCount:0,
projectId:1, projectId:1,