Merge branch 'Ashutosh_Task#67_Request_Demo' into Feature_Task_Management

This commit is contained in:
Vikas Nale 2025-04-19 11:06:14 +05:30
commit e236e4f5bf
4 changed files with 233 additions and 71 deletions

View File

@ -8,7 +8,7 @@ import { TasksRepository } from "../../repositories/TaskRepository";
import showToast from "../../services/toastService";
import Avatar from "../common/Avatar";
import { getBgClassFromHash } from "../../utils/projectStatus";
import {cacheData, getCachedData} from "../../slices/apiDataManager";
import { cacheData, getCachedData } from "../../slices/apiDataManager";
const schema = z.object({
comment: z.string().min(1, "Comment cannot be empty"),
@ -50,25 +50,30 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
setloading(true);
const resp = await TasksRepository.taskComments(sendComment);
setComment((prevItems) => [...prevItems, resp.data]);
const taskList = getCachedData("taskList")
const taskList = getCachedData("taskList");
const updatedTaskList = taskList.data.map((task) => {
if (task.id === resp.data.taskAllocationId) {
const existingComments = Array.isArray(task.comments) ? task.comments : [];
const existingComments = Array.isArray(task.comments)
? task.comments
: [];
return {
...task,
comments: [...existingComments, resp.data],
comments: [...existingComments, resp.data],
};
}
return task;
})
cacheData("taskList",{data:updatedTaskList,projectId:taskList.projectId})
});
cacheData("taskList", {
data: updatedTaskList,
projectId: taskList.projectId,
});
reset();
setloading(false);
showToast("Successfully Sent", "success");
// closeModal();
} catch (error) {
setloading( false );
console.log(error)
setloading(false);
console.log(error);
showToast(error.response.data?.message || "Something wrong", "error");
}
};
@ -85,7 +90,15 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
onClick={closeModal}
aria-label="Close"
></button>
<p className="fs-6 text-dark text-start">{`${ commentsData?.workItem?.workArea?.floor?.building?.name }`} <i class='bx bx-chevron-right'></i> {`${ commentsData?.workItem?.workArea?.floor?.floorName } `} <i class='bx bx-chevron-right'></i>{`${ commentsData?.workItem?.workArea?.areaName }`}<i class='bx bx-chevron-right'></i>{` ${commentsData?.workItem?.activityMaster?.activityName}`}</p>
<p className="fs-6 text-dark text-start">
{`${commentsData?.workItem?.workArea?.floor?.building?.name}`}{" "}
<i class="bx bx-chevron-right"></i>{" "}
{`${commentsData?.workItem?.workArea?.floor?.floorName} `}{" "}
<i class="bx bx-chevron-right"></i>
{`${commentsData?.workItem?.workArea?.areaName}`}
<i class="bx bx-chevron-right"></i>
{` ${commentsData?.workItem?.activityMaster?.activityName}`}
</p>
<ul
className="list-grouph px-0 mx-0 overflow-auto"
@ -104,8 +117,13 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
className={`li-wrapper d-flex justify-content-start align-items-start my-0 `}
>
<div class="avatar avatar-xs me-1">
<span class={`avatar-initial rounded-circle bg-label-primary}`}>
{`${data?.employee?.firstName.slice(0,1)} ${data?.employee?.lastName.slice(0,1)}`}
<span
class={`avatar-initial rounded-circle bg-label-primary}`}
>
{`${data?.employee?.firstName.slice(
0,
1
)} ${data?.employee?.lastName.slice(0, 1)}`}
</span>
</div>
@ -115,9 +133,7 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
className=" text-muted m-0 "
style={{ fontSize: "10px" }}
>
{moment.utc(data?.commentDate).local().fromNow()}
{moment.utc(data?.commentDate).local().fromNow()}
</p>
</div>
</div>

View File

@ -1,65 +1,108 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import "./page-auth.css";
import { AuthWrapper } from "./AuthWrapper";
import { useForm,Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import showToast from "../../services/toastService";
import AuthRepository from "../../repositories/AuthRepository";
import { MasterRespository } from "../../repositories/MastersRepository";
const mobileNumberRegex = /^(?:\d{10}|\d{3}[-\s]?\d{3}[-\s]?\d{4})$/;
const registerSchema = z.object({
orgName:z.string().min(1,{message:"Organization Name is required"}),
email:z.string().email(),
contactPerson:z.string().min(1,{message:"Person Name is required"}),
contactNo:z.string().min(1,{message: "Phone Number is required"})
.regex(mobileNumberRegex, {message:"Invalid phone number "}),
orgSize:z.string().min(1,{message:"please Select Organization Size "}),
organizatioinName: z
.string()
.min(1, { message: "Organization Name is required" }),
email: z.string().email(),
about: z
.string()
.min(1, { message: "Current Address is required" })
.max(500, { message: "Address cannot exceed 500 characters" }),
contactPerson: z.string().min(1, { message: "Person Name is required" }),
contactNumber: z
.string()
.min(1, { message: "Phone Number is required" })
.regex(mobileNumberRegex, { message: "Invalid phone number " }),
oragnizationSize: z
.string()
.min(1, { message: "please Select Organization Size " }),
industryId: z.string(),
terms: z.boolean().refine((val) => val === true, {
message: "Please accept the terms and conditions.",
}),
} )
});
const RegisterPage = () => {
const {register,handleSubmit,formState: { errors }} = useForm({
resolver:zodResolver(registerSchema)
})
const onSubmit= async(data)=>{
try
{
// const response = await AuthRepository.register( data );
showToast("Your Registration SuccessFully !")
} catch ( error )
{
console.log(error)
showToast(error.message,"error")
}
}
const [registered,setRegristered] = useState(false);
const [industries, setIndustries] = useState([]);
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: zodResolver(registerSchema),
});
const onSubmit = async (data) => {
try {
const response = await AuthRepository.requestDemo(data);
showToast("Your Registration SuccessFully !");
setRegristered(true);
} catch (error) {
// console.log(error);
showToast(error.message, "error");
}
};
useEffect(() => {
fetchIndustries();
}, []);
useEffect(() => {
}, [industries]);
const fetchIndustries = async () => {
try {
const response = await MasterRespository.getIndustries();
const industry = response.data;
setIndustries(industry);
} catch (error) {
showToast(error.message, "error");
}
};
return (
<AuthWrapper>
<>
{!registered && (<AuthWrapper>
<h4 className="mb-2">Adventure starts here 🚀</h4>
<p className="mb-3">Make your app management easy and fun!</p>
<form id="formAuthentication" className="mb-3" onSubmit={handleSubmit(onSubmit)}>
<form
id="formAuthentication"
className="mb-3"
onSubmit={handleSubmit(onSubmit)}
>
<div className="mb-3">
<label htmlFor="orgname" className="form-label">
<label htmlFor="organizatioinName" className="form-label">
Organization Name
</label>
<input
type="text"
className="form-control"
id="orgname"
{...register("orgName")}
name="orgName"
id="organizatioinName"
{...register("organizatioinName")}
name="organizatioinName"
placeholder="Enter your Organization Name"
autoFocus
/>
{errors.orgName && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.orgName.message}</div>}
{errors.organizatioinName && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.organizatioinName.message}
</div>
)}
</div>
<div className="mb-3">
<label htmlFor="email" className="form-label">
@ -73,8 +116,14 @@ const RegisterPage = () => {
placeholder="Enter your email"
{...register("email")}
/>
{errors.email && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.email.message}</div>}
{errors.email && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.email.message}
</div>
)}
</div>
<div className="mb-3 form-password-toggle">
<label className="form-label" htmlFor="contactperson">
@ -91,8 +140,14 @@ const RegisterPage = () => {
aria-describedby="contactperson"
/>
</div>
{errors.contactPerson && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.contactPerson.message}</div>}
{errors.contactPerson && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.contactPerson.message}
</div>
)}
</div>
<div className="mb-3 form-password-toggle">
<label className="form-label" htmlFor="contactnumber">
@ -102,37 +157,108 @@ const RegisterPage = () => {
<input
type="text"
id="contactnumber"
{...register("contactNo")}
{...register("contactNumber")}
className="form-control"
name="contactNo"
name="contactNumber"
placeholder="Contact Number"
aria-describedby="contactnumber"
/>
</div>
{errors.contactNo && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.contactNo.message}</div>}
{errors.contactNumber && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.contactNumber.message}
</div>
)}
</div>
<div className="mb-3 form-password-toggle">
<label className="form-label" htmlFor="orgsize">
<label className="form-label" htmlFor="contactnumber">
About Organization
</label>
<div className="input-group input-group-merge">
<textarea
id="about"
className="form-control"
placeholder="about"
aria-label="about"
aria-describedby="about"
{...register("about")}
></textarea>
</div>
{errors.about && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.about.message}
</div>
)}
</div>
<div className="mb-3 form-password-toggle">
<label className="form-label" htmlFor="oragnizationSize">
Organization Size
</label>
<div className="input-group input-group-merge">
<select
className="form-select"
id="orgsize"
name="orgSize"
{...register("orgSize")}
id="oragnizationSize"
name="oragnizationSize"
{...register("oragnizationSize")}
aria-label="Default select example"
>
<option value="">Number of Employees</option>
<option value="1">1-10 </option>
<option value="2">10-50</option>
<option value="3">50-100</option>
<option value="4">more than 100</option>
<option value="1-10">1-10</option>
<option value="10-50">10-50</option>
<option value="50-100">50-100</option>
<option value="100-200">100-200</option>
<option value="more than 200">more than 200</option>
</select>
</div>
{errors.orgSize && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.orgSize.message}</div>}
{errors.oragnizationSize && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.oragnizationSize.message}
</div>
)}
</div>
<div className="mb-3 form-password-toggle">
<label className="form-label" htmlFor="industryId">
Industry
</label>
<div className="input-group input-group-merge">
<select
className="form-select"
id="industryId"
name="industryId"
{...register("industryId")}
aria-label="Default select example"
>
<option value="">
Select Industry
</option>
{industries.length > 0 ? (
industries.map((item) => (
<option value={item.id} key={item.id}>
{item.name}
</option>
))
) : (
<option disabled>Loading industries...</option>
)}
</select>
</div>
{errors.industryId && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.industryId.message}
</div>
)}
</div>
<div className="mb-3">
<div className="form-check">
@ -157,8 +283,14 @@ const RegisterPage = () => {
</Link>
</label>
</div>
{errors.terms && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.terms.message}</div>}
{errors.terms && (
<div
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.terms.message}
</div>
)}
</div>
<button aria-label="Click me" className="btn btn-primary d-grid w-100">
Request Demo
@ -176,7 +308,20 @@ const RegisterPage = () => {
Back to login
</Link>
</p>
</AuthWrapper>
</AuthWrapper>)}
{registered && (<AuthWrapper>
<h6 className="mb-2">Thank you for contacting us</h6>
<h4 className="mb-3">We will get back to you soon</h4>
<Link
aria-label="Go to Login Page"
to="/auth/login"
className="d-flex align-items-center justify-content-center"
>
<i className="bx bx-chevron-left scaleX-n1-rtl bx-sm"></i>
Back to login
</Link>
</AuthWrapper>)}
</>
);
};

View File

@ -9,6 +9,7 @@ const AuthRepository = {
register: ( data ) => api.post( 'api/auth/register', data ),
resetPassword: ( data ) => api.post( '/api/auth/reset-password', data ),
forgotPassword: (data) => api.post( '/api/auth/forgot-password', data),
requestDemo: (data) => api.post('/api/auth/inquiry',data),
sendMail:(data)=>api.post("/api/auth/sendmail",data)
};

View File

@ -32,6 +32,6 @@ export const MasterRespository = {
getActivites: () => api.get( 'api/master/activities' ),
createActivity: (data) => api.post( 'api/master/activity',data ),
updateActivity:(id,data) =>api.post(`api/master/edit/${id}`,data),
getIndustries:()=> api.get('api/master/industries'),
}