average score and name default changed to duties modified modal

parent 728a8a82
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"redux-thunk": "^3.1.0", "redux-thunk": "^3.1.0",
"uuid": "^9.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"devDependencies": { "devDependencies": {
...@@ -16398,6 +16399,14 @@ ...@@ -16398,6 +16399,14 @@
"websocket-driver": "^0.7.4" "websocket-driver": "^0.7.4"
} }
}, },
"node_modules/sockjs/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/source-list-map": { "node_modules/source-list-map": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
...@@ -17746,9 +17755,13 @@ ...@@ -17746,9 +17755,13 @@
} }
}, },
"node_modules/uuid": { "node_modules/uuid": {
"version": "8.3.2", "version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": { "bin": {
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"redux-thunk": "^3.1.0", "redux-thunk": "^3.1.0",
"uuid": "^9.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {
......
...@@ -149,7 +149,7 @@ app.post('/createActivity',async (req, res) => { ...@@ -149,7 +149,7 @@ app.post('/createActivity',async (req, res) => {
let { data } = req.body; let { data } = req.body;
//data validation //data validation
if (!_.get(data, "aName", "") || !_.get(data, "aId", "") || !_.get(data, "type", "") || !_.get(data, "score", "")) { if (!_.get(data, "aName", "") || !_.get(data, "aId", "") || !_.get(data, "type", "") || !_.get(data, "score", "") || !_.get(data,"comments","")) {
res.status(401).json({ "error": "Invalid Activity data" }); res.status(401).json({ "error": "Invalid Activity data" });
return; return;
} }
...@@ -158,10 +158,10 @@ app.post('/createActivity',async (req, res) => { ...@@ -158,10 +158,10 @@ app.post('/createActivity',async (req, res) => {
res.status(401).json({ "message": "Score Should be between 1 to 5 or -1 to -5 only" }); res.status(401).json({ "message": "Score Should be between 1 to 5 or -1 to -5 only" });
return return
} }
if(data["comments"]===undefined){ // if(data["comments"]===undefined){
res.status(401).json({ "message": "need comments field" }); // res.status(401).json({ "message": "need comments field" });
return // return
} // }
data = { ...data, "recorded_date": new Date() }; data = { ...data, "recorded_date": new Date() };
data = Object.assign(data, { "_id": new ObjectId() }) data = Object.assign(data, { "_id": new ObjectId() })
...@@ -208,15 +208,15 @@ const calculateAverage = async(query) => { ...@@ -208,15 +208,15 @@ const calculateAverage = async(query) => {
.then(async(result) => { .then(async(result) => {
let activitiesList = result.activities; let activitiesList = result.activities;
let activitiesLength = activitiesList.length; let activitiesLength = activitiesList.length;
let score = activitiesList.reduce((acc, curr) => { return acc + curr.score }, 0); let score = activitiesList.reduce((acc, curr) => { return acc + Number(curr.score) }, 0);
let averageScore = 0; let averageScore = score / activitiesLength;
score < 0 // score < 0
? (averageScore = 0) // ? (averageScore = 0)
: (averageScore = score / activitiesLength); // : (averageScore = score / activitiesLength);
if (averageScore % 1 !== 0) { // if (averageScore % 1 !== 0) {
averageScore = averageScore.toFixed(1); averageScore = Number(averageScore).toFixed(1);
} // }
await db.collection("employees") await db.collection("employees")
.updateOne(query, { $set: { score: Number(averageScore) } }) .updateOne(query, { $set: { score: Number(averageScore) } })
......
...@@ -30,7 +30,7 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) { ...@@ -30,7 +30,7 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
// },[userDetails,id]) // },[userDetails,id])
useEffect(()=>{ useEffect(()=>{
if(reports !==null){ if(reports?.length !==null){
dispatch(calculateDefaultScore(reports)) dispatch(calculateDefaultScore(reports))
dispatch(calculateInitiativeScore(reports)) dispatch(calculateInitiativeScore(reports))
} }
...@@ -46,7 +46,7 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) { ...@@ -46,7 +46,7 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
{ title: "Comments", id: "comments", width: "40%" }, { title: "Comments", id: "comments", width: "40%" },
]; ];
if(loading && title =="Default")return <Loading/> if(loading && title =="Duties")return <Loading/>
if(!loading){ if(!loading){
return ( return (
...@@ -56,11 +56,11 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) { ...@@ -56,11 +56,11 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
onClick={handleClick} onClick={handleClick}
type="button" type="button"
className="flex items-center rounded-lg w-full py-2 px-2 mt-4 font-medium rtl:text-right bg-white text-gray-500 border border-[#B7B7B7] focus:ring-4 dark:border-gray-700 hover:bg-gray-100 gap-3" data-accordion-target="#accordion-collapse-body-2" aria-expanded="false" aria-controls="accordion-collapse-body-2" > className="flex items-center rounded-lg w-full py-2 px-2 mt-4 font-medium rtl:text-right bg-white text-gray-500 border border-[#B7B7B7] focus:ring-4 dark:border-gray-700 hover:bg-gray-100 gap-3" data-accordion-target="#accordion-collapse-body-2" aria-expanded="false" aria-controls="accordion-collapse-body-2" >
<div className="w-1/2 text-start ms-2">{title}</div> <span className="w-1/2 text-start ms-2">{title}</span>
<div className="w-1/2 flex justify-between"> <span className="w-1/2 flex justify-between">
Average Score :{title === "Default" ? defaultAvgScore : initiativeAvgScore} Average Score :{title === "Duties" ? defaultAvgScore : initiativeAvgScore}
<ModalButton type={`${title === "Default" ? "default" : "initiative"}`} handleAddActivity={handleAddActivity}/> <ModalButton type={`${title === "Duties" ? "duties" : "initiative"}`} handleAddActivity={handleAddActivity}/>
</div> </span>
<svg data-accordion-icon className="w-3 h-3 rotate-180 shrink-0" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6"> <svg data-accordion-icon className="w-3 h-3 rotate-180 shrink-0" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
<path <path
stroke="currentColor" stroke="currentColor"
......
...@@ -12,7 +12,7 @@ function LeftSidebar() { ...@@ -12,7 +12,7 @@ function LeftSidebar() {
return ( return (
<div className=" w-[33%] flex flex-col px-[5px]"> <div className=" w-[33%] flex flex-col px-[5px]">
<p className="text-xl text-blue-400 font-semibold pl-4 mt-3"> <p className="text-xl text-blue-400 font-semibold">
My Reportees My Reportees
</p> </p>
{ {
...@@ -21,11 +21,11 @@ function LeftSidebar() { ...@@ -21,11 +21,11 @@ function LeftSidebar() {
{reportees?.map(({ empName, score, empId }) => ( {reportees?.map(({ empName, score, empId }) => (
<Link <Link
to={`/viewreportee/${empId}`} to={`/viewreportee/${empId}`}
className={`flex items-center hover:bg-indigo-500 hover:text bg-${Number(id) == empId ? "indigo-200" : "white" className={`flex items-center hover:bg-blue-400 hover:text-white hover:rounded-2xl bg-${Number(id) == empId ? "indigo-200" : "white"
} p-2 justify-between mb-1 w-full`} } p-2 justify-between mb-1 w-full`}
key={empId} key={empId}
> >
<img src="/man.png" width="18px" height="18px" /> {/* <img src="/man.png" width="18px" height="18px" /> */}
<p className="w-[80%] text-left">{empName}</p> <p className="w-[80%] text-left">{empName}</p>
<p className={`w-[30px] h-[30px] rounded-full flex items-center text-white justify-center ${scoreColor(score)}`}> <p className={`w-[30px] h-[30px] rounded-full flex items-center text-white justify-center ${scoreColor(score)}`}>
{score} {score}
......
import axios from "axios"; import axios from "axios";
import React, { useMemo, useEffect, useState, useCallback } from "react"; import React, { useMemo, useEffect, useState, useCallback } from "react";
import { base_url } from "../../utils/constants"; import { base_url } from "../../utils/constants";
import { v4 as uuidv4 } from 'uuid';
import Loading from "../loading Component/Loading"; import Loading from "../loading Component/Loading";
export default function MyModal({ visible, onClose ,type,handleAddActivity}) { export default function MyModal({ visible, onClose, type, handleAddActivity }) {
const [activitiesList, setActivitiesList] = useState([]) const [activitiesList, setActivitiesList] = useState([])
const [enableSubmit,setEnableSubmit]=useState(false) const [enableSubmit, setEnableSubmit] = useState(false)
const [scoreType,setScoreType]=useState(1) const [activityData, setActivityData] = useState({ aName: "", aId: "", type: type, score: 0, comments: "" })
const [activityData,setActivityData]=useState({aName:"",aId:"",type:type,score:0,comments:""}) const [activityType, setActivtyType] = useState("")
const [activityType,setActivtyType]=useState("")
const [showCustActivity, setShowActivity] = useState(false); const [showCustActivity, setShowActivity] = useState(false);
const [custActivity, setCustActivity] = useState('')
const [modalLoading, setModalLoading] = useState(true) const [modalLoading, setModalLoading] = useState(true)
const [scoreRender, setScoreRender] = useState([]);
const [showScore, setShowScore] = useState(false)
const getActivitysList= async(type)=>{ const getActivitysList = async (type) => {
const activities=await axios.get(`${base_url}/activities`) const activities = await axios.get(`${base_url}/activities`)
const response= await activities.data.filter((item)=>item.type==type) const response = await activities.data.filter((item) => item.type == type)
setActivitiesList(response) setActivitiesList(response)
setModalLoading(false) setModalLoading(false)
} }
const handleActivityName = (e) => { const handleActivityName = (e) => {
setActivityData({...activityData,aName:e.target.value,aId:e.target.options[e.target.selectedIndex].id}) setActivityData({ ...activityData, aName: e.target.value, aId: e.target.options[e.target.selectedIndex].id })
} }
const handleScoreChange=(value)=>{ const handleCustumActivity = (e) => {
setActivityData({...activityData,score:(scoreType)*(value)}) const randomId = uuidv4();
setActivityData({ ...activityData, aName: e.target.value, aId: randomId })
} }
function handlePerformance (value){
setScoreType(value) const handleScoreChange = (value) => {
setActivityData({ ...activityData, score: value })
}
const handlePerformance=(value)=> {
let appreciateScores = [0, 1, 2, 3, 4, 5]
let depreciateScores = [-0, -1, -2, -3, -4, -5]
if (value == 1) {
setActivityData({ ...activityData, score: 0 })
setScoreRender(appreciateScores)
setShowScore(true)
}
else if (value == -1) {
setActivityData({ ...activityData, score: 0 })
setScoreRender(depreciateScores)
setShowScore(true)
}
} }
const handleComments=(e)=>{ const handleComments = (e) => {
// e.stopPropagation() setActivityData({ ...activityData, comments: e.target.value })
setActivityData({...activityData,comments:e.target.value})
} }
const handleSubmit=(e)=>{ const handleSubmit = (e) => {
onClose() onClose()
setShowActivity(false) setShowActivity(false)
handleAddActivity(activityData) handleAddActivity(activityData)
} }
useEffect(()=>{handleScoreChange(activityData.score)},[scoreType])
useEffect(() => { useEffect(() => {
if (activityData.aName !== "" && activityData.aId !== "" && activityData.score != 0 || -0) { if (activityData.aName !== "" && activityData.aId !== "" && activityData.comments !== "" && activityData.score != (0 || -0)) {
setEnableSubmit(true); setEnableSubmit(true);
} else { } else {
setEnableSubmit(false); setEnableSubmit(false);
} }
}, [activityData]); }, [activityData]);
const SentenceCase=(type)=>{ const SentenceCase = (type) => {
let str=type; let str = type;
setActivtyType(str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()) setActivtyType(str.charAt(0).toUpperCase() + str.slice(1).toLowerCase())
} }
useEffect(()=>{ useEffect(() => {
SentenceCase(type) SentenceCase(type)
if (visible===false){ if (visible === false) {
setActivityData({aName:"",aId:"",type:type,score:0,comments:""}) setActivityData({ aName: "", aId: "", type: type, score: 0, comments: "" })
}else{ } else {
getActivitysList(type); getActivitysList(type);
setModalLoading(true) setModalLoading(true)
} }
},[visible,type]); }, [visible, type]);
const handleCustBtn = (e) => {
e.preventDefault();
setShowActivity(!showCustActivity);
setActivityData({ ...activityData, aName: "", aId: "" })
}
...@@ -76,50 +99,46 @@ export default function MyModal({ visible, onClose ,type,handleAddActivity}) { ...@@ -76,50 +99,46 @@ export default function MyModal({ visible, onClose ,type,handleAddActivity}) {
return ( return (
<> <>
<div className="absolute w-full h-full inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex items-center justify-center" onClick={(e) => e.stopPropagation()}> <div className="absolute w-full h-full inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex items-center justify-center" onClick={(e) => e.stopPropagation()}>
<div className="bg-white rounded-md lg:w-4/12 sm:w-100"> {
<div className=" text-white py-3 pl-2 bg-blue-500 rounded-md">{activityType} Activity</div> (!modalLoading) ? <div className="bg-white rounded-md lg:w-4/12 sm:w-100">
<div className=" text-white py-3 pl-2 bg-blue-500 rounded-md text-start">{activityType}</div>
<div> <div>
<div> <div>
{ <form className=" p-2 max-w-sm mx-auto text-[12px]" onClick={(e) => e.stopPropagation()}>
(!modalLoading) ? <form className=" p-2 max-w-sm mx-auto text-[12px]" onClick={(e) => e.stopPropagation()}>
<div className="flex items-center justify-between my-5"> <div className="flex items-center justify-between my-5">
<label htmlFor="countries">SELECT ACTIVITY: </label> <label htmlFor="countries">SELECT ACTIVITY<span className="text-[15px]">*</span>: </label>
<select disabled={showCustActivity} className="bg-gray-50 ml-2 w-7/12 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" onChange={(e)=>handleActivityName(e)}> <select disabled={showCustActivity} className="bg-gray-50 ml-2 w-6/12 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" onChange={(e) => handleActivityName(e)} value={activityData.aName}>
<option id="" value="">Select</option> <option id="" value="">Select</option>
{ {
activitiesList && activitiesList.map((activity)=><option className=" w-7/12" key={activity.aId} id={activity.aId} value={activity.aName}>{activity.aName}</option>) activitiesList && activitiesList.map((activity) => <option className=" w-7/12" key={activity.aId} id={activity.aId} value={activity.aName}>{activity.aName}</option>)
} }
</select> </select>
<button onClick={(e) => {e.preventDefault(); setShowActivity(!showCustActivity)}} className="bg-blue-400 ml-2 w-5/12 text-white px-2 py-1 rounded hover:scale-95 transition text-sm">Custom Activity</button> <button onClick={(e) => { handleCustBtn(e) }} className="bg-blue-400 ml-2 w-2/12 text-white py-1 rounded hover:scale-95 transition text-sm">Custom</button>
</div> </div>
<div className={`flex items-center ${!showCustActivity && 'hidden'}`}> <div className={`flex items-center ${!showCustActivity && 'hidden'}`}>
<label className={`font-medium dark:text-gray-300 mr-2`}>Custom Activity:</label> <label className={`font-medium dark:text-gray-300 mr-2`}>Custom Activity<span className="text-[15px]">*</span>:</label>
<input type="text" value={custActivity} placeholder="Enter Activity name" name="performance" className={`border border-gray-300 rounded p-2 `} onChange={(e)=>setCustActivity(e.target.value)}/> <input type="text" value={activityData.aName} placeholder="Enter Activity name" name="performance" className={`border border-gray-300 rounded p-2 `} onChange={(e) => handleCustumActivity(e)} />
</div> </div>
<div className="flex items-center mb-4 "> <div className="flex items-center mb-4 ">
<label htmlFor="appreciate" className=" font-medium dark:text-gray-300">APPRECIATION:</label> <label htmlFor="appreciate" className=" font-medium dark:text-gray-300">APPRECIATION<span className="text-[15px]">*</span>:</label>
<input id="appreciate" type="radio" value="appreciate" name="performance" className="w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600" onChange={()=>handlePerformance(1)}/> <input id="appreciate" type="radio" value="appreciate" name="performance" className="w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600" onChange={() => handlePerformance(1)} />
<label htmlFor="depreciate" className="ms-2 font-medium dark:text-gray-300">DEPRECIATION:</label> <label htmlFor="depreciate" className="ms-2 font-medium dark:text-gray-300">DEPRECIATION<span className="text-[15px]">*</span>:</label>
<input id="depreciate" type="radio" value="depreciate" name="performance" className="w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600" onChange={()=>handlePerformance(-1)} /> <input id="depreciate" type="radio" value="depreciate" name="performance" className="w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600" onChange={() => handlePerformance(-1)} />
</div> </div>
<div className="flex "> <div className={`flex ${!showScore && 'hidden'}`}>
<span>SCORE: </span> <span>SCORE<span className="text-[15px]">*</span>: </span>
<select className="border w-1/5 ms-1" onChange={(e)=>handleScoreChange(e.target.value)}> <select className="border w-1/5 ms-1" onChange={(e) => handleScoreChange(e.target.value)} value={activityData.score}>
<option value={0}>Select</option> <option value={0}>Select</option>
<option value={1}>1</option> {
<option value={2}>2</option> scoreRender && scoreRender.map((score) => <option value={score}>{score}</option>)
<option value={3}>3</option> }
<option value={4}>4</option>
<option value={5}>5</option>
</select> </select>
</div> </div>
<div className="flex items-center my-5"> <div className="flex items-center my-5">
<label htmlFor="comments" className="block w-3/12 mb-20 text-start font-medium dark:text-white">COMMENTS :</label> <label htmlFor="comments" className="block w-3/12 mb-20 text-start font-medium dark:text-white">COMMENTS<span className="text-[15px]">*</span>:</label>
<textarea id="comments" style={{resize:"none"}} rows="4" className="block ml-2 p-2.5 w-9/12 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Activity comments (optional)" onChange={(e)=>handleComments(e)} <textarea id="comments" style={{ resize: "none" }} rows="4" className="block ml-2 p-2.5 w-9/12 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Comments" onChange={(e) => handleComments(e)}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
onKeyDown={(e) => { onKeyDown={(e) => {
// Prevent propagation of space key press
if (e.key === " ") { if (e.key === " ") {
// e.preventDefault() // e.preventDefault()
e.stopPropagation(); e.stopPropagation();
...@@ -134,19 +153,18 @@ export default function MyModal({ visible, onClose ,type,handleAddActivity}) { ...@@ -134,19 +153,18 @@ export default function MyModal({ visible, onClose ,type,handleAddActivity}) {
}}></textarea> }}></textarea>
</div> </div>
<div className="flex items-center justify-end mb-3"> <div className="flex items-center justify-end mb-3">
<button onClick={() => {setShowActivity(false); onClose()}} className="px-3 py-2 rounded-md bg-gray-700 text-white ">Cancel</button> <button onClick={() => { setShowActivity(false); onClose() }} className="px-3 py-2 rounded-md bg-gray-700 text-white ">Cancel</button>
{ {
enableSubmit?<button type="button" className="px-3 py-2 ml-5 bg-blue-500 text-white rounded-md" onClick={handleSubmit}>Submit</button>: enableSubmit ? <button type="button" className="px-3 py-2 ml-5 bg-blue-500 text-white rounded-md" onClick={handleSubmit}>Submit</button> :
<button type="button" className="px-3 py-2 ml-5 bg-gray-400 text-white rounded" disabled={!enableSubmit} title="Please fill all fileds to submit">Submit</button> <button type="button" className="px-3 py-2 ml-5 bg-gray-400 text-white rounded" disabled={!enableSubmit} title="Please fill all fileds to submit">Submit</button>
} }
</div> </div>
</form>
</form>:null
}
</div>
</div> </div>
</div> </div>
</div> : null
}
</div> </div>
</> </>
) )
......
...@@ -3,27 +3,27 @@ import Loading from "../loading Component/Loading"; ...@@ -3,27 +3,27 @@ import Loading from "../loading Component/Loading";
function Table({headers, data,loading, maxHeight}) { function Table({headers, data,loading, maxHeight}) {
if(loading) return <Loading/> if(loading) return <Loading/>
else
return ( return (
<div className={` overflow-auto sm:rounded-lg p-4 bg-gray-100`}> <div className={` overflow-auto sm:rounded-lg p-4 bg-gray-100`}>
<table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 bg-transparent justify-center border-separate border-spacing-y-2"> <table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 bg-transparent justify-center border-separate border-spacing-y-2">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-white"> <thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-white">
<tr className="mb-2"> <tr className="mb-2">
{headers.map((item,index) => ( {headers?.map((item,index) => (
<th key={index} scope="col" className={`px-6 py-4 w-[${item.width}]`} > <th key={index} scope="col" className={`px-6 py-4 w-[${item.width}]`} >
{item.title} {item.title}
</th> </th>
))} ))}
</tr> </tr>
</thead> </thead>
{ (data?.length)? {
<tbody> (data?.length)?<tbody>
{ {
data?.map((item, index) => ( data?.map((item, index) => (
<tr className="bg-white dark:bg-gray-800 dark:border-gray-700 dark:text-white hover:bg-gray-50 dark:hover:bg-gray-600"> <tr key={item.id} className="bg-white dark:bg-gray-800 dark:border-gray-700 dark:text-white hover:bg-gray-50 dark:hover:bg-gray-600">
{ {
headers?.map(({render, id}) => ( headers?.map(({render, id}) => (
<td className="px-6 py-4 listData" >{render ? render(item[id]) : item[id] === "" ? "NA" : item[id] }</td> <td key={`${item.id}_${id}`} className="px-6 py-4 listData" >{render ? render(item[id]) : item[id] === "" ? "NA" : item[id] }</td>
)) ))
} }
</tr> </tr>
......
...@@ -38,10 +38,10 @@ function Reports() { ...@@ -38,10 +38,10 @@ function Reports() {
const handleAccordian = (value) => { const handleAccordian = (value) => {
switch (value) { switch (value) {
case "Default": case "Duties":
setOpen({ ...open, "accordianOne": !open["accordianOne"], "accordianTwo": false }); setOpen({ ...open, "accordianOne": !open["accordianOne"], "accordianTwo": false });
break; break;
case "Initiative": case "Initiatives":
setOpen({ ...open, "accordianOne": false, "accordianTwo": !open["accordianTwo"] }); setOpen({ ...open, "accordianOne": false, "accordianTwo": !open["accordianTwo"] });
break; break;
default: default:
...@@ -151,14 +151,11 @@ function Reports() { ...@@ -151,14 +151,11 @@ function Reports() {
</div> </div>
</div> </div>
<div className=""> <div className="">
{/* <div className="container mx-auto mt-4 flex justify-end pe-4">
<DateRangePicker getReports={getReports} />
</div> */}
<div className=""> <div className="">
<Accordion title="Default" open={open.accordianOne} handleAccordian={handleAccordian} data={activities?.default} handleAddActivity={handleAddActivity} /> <Accordion title="Duties" open={open.accordianOne} handleAccordian={handleAccordian} data={activities?.duties} handleAddActivity={handleAddActivity} />
</div> </div>
<div className=""> <div className="">
<Accordion title="Initiative" open={open.accordianTwo} handleAccordian={handleAccordian} data={activities?.initiative} handleAddActivity={handleAddActivity} /> <Accordion title="Initiatives" open={open.accordianTwo} handleAccordian={handleAccordian} data={activities?.initiative} handleAddActivity={handleAddActivity} />
</div> </div>
</div> </div>
</div> </div>
......
...@@ -24,16 +24,25 @@ const reportSlice = createSlice({ ...@@ -24,16 +24,25 @@ const reportSlice = createSlice({
return initialState return initialState
}, },
calculateDefaultScore:(state, action)=>{ calculateDefaultScore:(state, action)=>{
const defaultItems = action.payload?.filter(item => item.type === "default"); if(action.payload===undefined){
const totalDefaultScore = defaultItems?.reduce((acc, curr) => acc+ curr.score, 0); return {...state,defaultAvgScore :0}
const defaultAvgScore = totalDefaultScore > 0 ? totalDefaultScore / defaultItems.length : 0; }else{
return {...state,defaultAvgScore :defaultAvgScore.toFixed(1)} const dutiesItems = action.payload?.filter(item => item.type === "duties");
const totalDutiesScore =dutiesItems?.length? dutiesItems?.reduce((acc, curr) => acc+ Number(curr.score), 0):0;
const defaultAvgScore =totalDutiesScore===0?0: Number(totalDutiesScore) / Number(dutiesItems?.length);
return {...state,defaultAvgScore :Number(defaultAvgScore).toFixed(1)}
}
}, },
calculateInitiativeScore:(state,action)=>{ calculateInitiativeScore:(state,action)=>{
const defaultItems = action.payload?.filter(item => item.type === "initiative"); if(action.payload===undefined){
const totalDefaultScore = defaultItems?.reduce((acc, curr) => acc+ curr.score, 0); return {...state,initiativeAvgScore:0}
const initialAvgScore = totalDefaultScore > 0 ? totalDefaultScore / defaultItems.length : 0; }
return {...state,initiativeAvgScore :initialAvgScore.toFixed(1)} else{
const initiatiesItems = action.payload?.filter(item => item.type === "initiative");
const totalInitiateScore =initiatiesItems?.length? (initiatiesItems?.reduce((acc, curr) => acc+ Number(curr.score), 0)):0;
const initialAvgScore =totalInitiateScore===0?0: Number(totalInitiateScore) / Number(initiatiesItems?.length) ;
return {...state,initiativeAvgScore :Number(initialAvgScore).toFixed(1)}
}
}, },
}, },
......
const scoreColor = (value) => { const scoreColor = (value) => {
if (value >= 0 && value < 1) { if (value < 1) {
return 'bg-red-400'; return 'bg-red-400';
} else if (value >= 1 && value < 2) { } else if (value >= 1 && value < 2) {
return 'bg-red-300'; return 'bg-red-300';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment