Commit 223aa5fb authored by Your Name's avatar Your Name

Latest pull

parent 59c0b16b
const express = require('express') const express = require("express");
const { connectToDb, getDb } = require("./db") const { connectToDb, getDb } = require("./db");
const { ObjectId } = require("mongodb") const cors = require("cors");
const cors = require("cors") const moment = require("moment");
const { ObjectId } = require("mongodb");
const app = express(); const app = express();
const _ = require('lodash');
app.use(express.json()) app.use(express.json());
app.use(cors()) app.use(cors());
//test commit
connectToDb((err) => { connectToDb((err) => {
if (!err) { if (!err) {
app.listen(4000, () => { app.listen(4000, () => {
console.log('app listening on port 4000') console.log("app listening on port 4000");
}) });
db = getDb() db = getDb();
} }
}) });
//to get all the employees data //to get all the employees data
app.get('/employees', (req, res) => { app.get("/employees", (req, res) => {
db.collection('employees').find().toArray() db.collection("employees")
.then(result => { res.send(result) }) .find()
.catch(error => res.status(401).send(error)) .toArray()
}) .then((result) => {
res.send(result);
})
.catch((error) => res.status(401).send(error));
});
//to get only individual employee data //to get only individual employee data
app.get('/employee/:id', (req, res) => { app.get("/employee/:id", (req, res) => {
let Id = parseInt(req.params.id); let Id = parseInt(req.params.id);
db.collection('employees').findOne({empId:Id},{projection:{_id:false}}) db.collection("employees")
.then(result => { res.send(result) }) .findOne({ empId: Id }, { projection: { _id: false } })
.catch(error => res.status(401).send(error)) .then((result) => {
}) res.send(result);
})
.catch((error) => res.status(401).send(error));
});
//to get activities to display //to get activities to display
app.get('/activities', (req, res) => { app.get("/activities", (req, res) => {
db.collection('activities_master').find().toArray() db.collection("activities_master")
.then(result => { res.send(result) }) .find()
.catch(error => res.status(401).send(error)) .toArray()
}) .then((result) => {
res.send(result);
})
.catch((error) => res.status(401).send(error));
});
/* /*
Example of post Data Example of post Data
...@@ -48,46 +59,51 @@ Example of post Data ...@@ -48,46 +59,51 @@ Example of post Data
,"page":1,"perPage":10, ,"page":1,"perPage":10,
"searchText":"eng" "searchText":"eng"
}*/ }*/
app.post('/getreportees', (req, res) => { app.post("/getreportees", (req, res) => {
let reporteesArray = req.body.reportees || []; let reporteesArray = req.body.reportees || [];
let sortBy=req.body.sort?req.body.sort.type || "_id" :"_id" let sortBy = req.body.sort ? req.body.sort.type || "_id" : "_id";
let sortByOrder=req.body.sort?parseInt(req.body.sort.order)|| 1: 1; let sortByOrder = req.body.sort ? parseInt(req.body.sort.order) || 1 : 1;
let page = req.body.page?parseInt(req.body.page) || 1 : 1; let page = req.body.page ? parseInt(req.body.page) || 1 : 1;
let limit = req.body.perPage?parseInt(req.body.perPage) || 10: 10; let limit = req.body.perPage ? parseInt(req.body.perPage) || 10 : 10;
let skip = (page - 1) * limit || 0; let skip = (page - 1) * limit || 0;
let query = { empId: { $in: reporteesArray } }; let query = { empId: { $in: reporteesArray } };
if(req.body.searchText){ let aggre = [{ $match: { empId: { $in: reporteesArray } } }];
let searchText = req.body.searchText.trim();
let searchStr = new RegExp(searchText, 'ig'); if (req.body.searchText) {
query = Object.assign(query, { let searchText = req.body.searchText.trim();
"$or": [ let searchStr = new RegExp(searchText, "ig");
{ 'empId': searchStr }, let orCondation = {
{ 'empName': searchStr }, $or: [
{"designation":searchStr} { empId: searchStr },
] { empName: searchStr },
}); { designation: searchStr },
} ],
db.collection('employees').find(query, { projection: { _id: false } }) };
.skip(skip) aggre.push({ $match: orCondation });
.sort({[sortBy]:sortByOrder})
.limit(limit) query = Object.assign(query);
.toArray() }
.then(result => { aggre.push({ $sort: { [sortBy]: sortByOrder } });
// Get the total count of data let facet = {
db.collection('employees').countDocuments(query) data: [{ $skip: skip }, { $limit: limit }],
.then(totalCount => { totalCount: [{ $count: "count" }],
res.send({ };
totalcount: totalCount, aggre.push({ $facet: facet });
currentPage: page, aggre.push({ $unwind: { path: "$totalCount" } });
totalPages: Math.ceil(totalCount / limit), db.collection("employees")
data: result, .aggregate(aggre)
}); .toArray()
}) .then((result) => {
.catch(error => res.status(401).send(error)); if (result && result.length) {
}) res.json({ ...result[0] });
.catch(error => res.status(401).send(error)); } else {
res.json({ data: [], totalCount: { count: 0 } });
}
})
.catch((error) => res.status(401).send(error));
}); });
//Example of post Data //Example of post Data
/* /*
{ {
...@@ -96,20 +112,26 @@ app.post('/getreportees', (req, res) => { ...@@ -96,20 +112,26 @@ app.post('/getreportees', (req, res) => {
"aName":"timesheet", "aName":"timesheet",
"aId":"D001", "aId":"D001",
"type":"default", "type":"default",
"recorded_date":"2024-03-12",
"score":3, "score":3,
"comments":"very good" "comments":"very good"
} }
} }
*/ */
app.post('/create-performance',(req,res)=>{ app.post('/createActivity',(req,res)=>{
const empId = req.body.empId || null; const empId = req.body.empId || null;
if(!empId){ if(!empId){
res.status(401).json({"message":"Employee id is missing"}); res.status(401).json({"message":"Employee id is missing"});
return return
}else{ }else{
let {data} = req.body; let {data} = req.body;
data = {...data, "recorded_date": new Date(data['recorded_date']) }; data = {...data, "recorded_date": new Date() };
data = Object.assign(data, {"_id":new ObjectId()})
if(!_.get(data,"aName", "") || !_.get(data,"aId", "") || !_.get(data,"type", "") || !_.get(data,"score", "") ){
res.json({"error":"Invalied Activity data"});
return;
}
let query = {empId:empId }; let query = {empId:empId };
db.collection('performance_master').findOne(query).then( (result)=>{ db.collection('performance_master').findOne(query).then( (result)=>{
if(result){ if(result){
...@@ -123,7 +145,8 @@ app.post('/create-performance',(req,res)=>{ ...@@ -123,7 +145,8 @@ app.post('/create-performance',(req,res)=>{
res.json({"error":error}); res.json({"error":error});
}); });
}else{ }else{
let insertData = { empId:empId, activities:[]}; let insertData = { empId:empId, activities:[]};
insertData.activities.push(data); insertData.activities.push(data);
db.collection('performance_master').insertOne(insertData).then(async (result)=>{ db.collection('performance_master').insertOne(insertData).then(async (result)=>{
await calculateAverage(query); await calculateAverage(query);
...@@ -146,27 +169,78 @@ app.post('/create-performance',(req,res)=>{ ...@@ -146,27 +169,78 @@ app.post('/create-performance',(req,res)=>{
}) })
//calculating average score and updating into employees data //calculating average score and updating into employees data
const calculateAverage= (query)=>{ const calculateAverage = (query) => {
return new Promise((res,rej)=>{ return new Promise((res, rej) => {
db.collection('performance_master').findOne(query).then((result)=>{ db.collection("performance_master")
let activitiesList=result.activities; .findOne(query)
let activitiesLength=activitiesList.length; .then((result) => {
let score=activitiesList.reduce((acc,curr)=>{ let activitiesList = result.activities;
return (acc) + (curr.score) let activitiesLength = activitiesList.length;
},0) let score = activitiesList.reduce((acc, curr) => { return acc + curr.score}, 0);
let averageScore=0 let averageScore = 0;
score<0?averageScore=0:(averageScore=(score/activitiesLength)) score < 0
db.collection("employees").updateOne(query,{$set:{score:averageScore}}) ? (averageScore = 0)
.then((result)=>{ : (averageScore = score / activitiesLength);
res(result)
}) if (averageScore % 1 !== 0) {
.catch((error)=>rej(error)) averageScore = averageScore.toFixed(1);
}) }
.catch((error)=>{
rej(error) db.collection("employees")
}) .updateOne(query, { $set: { score: averageScore } })
}); .then((result) => {
res(result);
})
.catch((error) => rej(error));
})
.catch((error) => {
rej(error);
});
});
};
//sending filtered activities data
/*Example post data
{
"empId":41689,
"fromDate":"2024-03-10",
"toDate":"2024-03-14"
} }
*/
app.post("/getActivities", (req, res) => {
let { empId, fromDate, toDate, today } = req.body;
if (!empId || typeof empId=="string") {
res.status(401).json({ message: "Employee id is missing/ EmpId should be string only" });
return;
} else {
let query = {
empId: empId,
};
if (fromDate && toDate) {
fromDate = new Date(fromDate)
toDate = new Date(toDate);
toDate.setHours(23);
toDate.setMinutes(59);
toDate.setSeconds(59);
query["activities.recorded_date"] = {
$gte: new Date(fromDate),
$lte: new Date(toDate),
};
} else {
// If fromDate and toDate are not provided, fetch data for the last 90 days
query["activities.recorded_date"] = {
$gte: moment().subtract(90, "days").toDate(),
$lte: moment().toDate(),
};
}
db.collection("performance_master")
.findOne(query)
.then((results) => {
res.json(results);
})
.catch((error) => {
console.error("Error fetching data:", error);
res.status(500).json({ message: "Error fetching data" });
});
}
});
...@@ -2,6 +2,7 @@ import {BrowserRouter, Routes, Route} from 'react-router-dom'; ...@@ -2,6 +2,7 @@ import {BrowserRouter, Routes, Route} from 'react-router-dom';
import Home from "./pages/home"; import Home from "./pages/home";
import Dashboard from './pages/dashboard'; import Dashboard from './pages/dashboard';
import Layout from './pages/layout'; import Layout from './pages/layout';
import Reports from './pages/reports';
import './App.css'; import './App.css';
function App() { function App() {
...@@ -10,6 +11,7 @@ function App() { ...@@ -10,6 +11,7 @@ function App() {
<Routes> <Routes>
<Route path='/' element={<Home />}/> <Route path='/' element={<Home />}/>
<Route path=":id/dashboard" element={<Layout><Dashboard/></Layout>}/> <Route path=":id/dashboard" element={<Layout><Dashboard/></Layout>}/>
<Route path=":id/reports" element={<Layout><Reports/></Layout>}/>
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>
); );
......
import React from 'react'; import React from 'react';
import {Link} from 'react-router-dom'; import {useNavigate} from 'react-router-dom';
import { useDispatch } from 'react-redux';
import clearStore from '../../utils/clearStore';
function Header() { function Header() {
const dispatch = useDispatch();
const navigate = useNavigate()
const handleLogout = () => {
navigate('/');
clearStore(dispatch)
}
return ( return (
<div className="flex items-center justify-between py-5 px-10"> <div className="flex items-center justify-between py-5 px-10">
<img src="/logo.png"/> <img src="/logo.png"/>
<div className="flex items-center"> <div className="flex items-center">
<img src="/power-button.png" width="30px" height="30px"/> <img src="/power-button.png" width="30px" height="30px"/>
<button className="ml-2 -mt-1 text-2xl" > <button className="ml-2 -mt-1 text-2xl" onClick={handleLogout}>
<Link to="/"> Logout
Logout
</Link>
</button> </button>
</div> </div>
</div> </div>
......
import axios from "axios";
import React, { useMemo, useEffect, useState, useCallback } from "react";
import { base_url } from "../../utils/constants";
export default function MyModal({ visible, onClose ,type}) {
const [activitiesList, setActivitiesList] = useState([])
const [enableSubmit,setEnableSubmit]=useState(false)
const [scoreType,setScoreType]=useState(1)
const [activityData,setActivityData]=useState({aName:"",aId:"",type:type,score:0,comments:""})
const getActivitysList= async()=>{
const activities=await axios.get(`${base_url}/activities`)
const response= await activities.data.filter((item)=>item.type==type)
setActivitiesList(response)
}
const handleActivityName = (e) => {
setActivityData({...activityData,aName:e.target.value,aId:e.target.options[e.target.selectedIndex].id})
}
const handleScoreChange=(value)=>{
setActivityData({...activityData,score:(scoreType)*(value)})
}
function handlePerformance (value){
setScoreType(value)
}
const handleComments=(e)=>{
setActivityData({...activityData,comments:e.target.value})
}
const handleSubmit=(e)=>{
onClose()
console.log(activityData)
}
useEffect(()=>{handleScoreChange(activityData.score)},[scoreType])
useEffect(() => {
if (activityData.aName !== "" && activityData.aId !== "" && activityData.comments !== "" && activityData.score != 0 || -0) {
setEnableSubmit(true);
} else {
setEnableSubmit(false);
}
}, [activityData]);
useEffect(()=>{
if (visible===false){
setActivityData({aName:"",aId:"",type:type,score:0,comments:""})
}else{
getActivitysList();
}
},[visible,type])
if (!visible) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex items-center justify-center">
<div className="bg-white rounded lg:w-4/12 sm:w-100">
<div className=" text-white py-3 pl-2 bg-blue-500">Default Activity</div>
<div>
<div>
<form className=" p-2 max-w-sm mx-auto">
<div className="flex items-center my-5">
<label htmlFor="countries">Select Activity: </label>
<select 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)}>
<option id="" value="" className="text-[16px]">Select</option>
{
activitiesList && activitiesList.map((activity)=><option className="text-[16px] w-7/12" key={activity.aId} id={activity.aId} value={activity.aName}>{activity.aName}</option>)
}
</select>
</div>
<div className="flex items-center mb-4 ">
<label htmlFor="appreciate" className=" text-sm font-medium text-gray-900 dark:text-gray-300">Appreciation:</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)}/>
<label htmlFor="depreciate" className="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">Depreciation:</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)} />
</div>
<div className="flex ">
<span>Score</span>
<select className="border w-1/5" onChange={(e)=>handleScoreChange(e.target.value)}>
<option value={0}>Select</option>
<option value={1}>1</option>
<option value={2}>2</option>
<option value={3}>3</option>
<option value={4}>4</option>
<option value={5}>5</option>
</select>
</div>
<div className="flex items-center my-5">
<label htmlFor="comments" className="block w-3/12 mb-20 text-sm font-medium text-gray-900 dark:text-white">Comments :</label>
<textarea id="comments" rows="4" className="block ml-2 p-2.5 w-9/12 text-sm text-gray-900 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" onChange={(e)=>handleComments(e)}></textarea>
</div>
<div className="flex items-center justify-end mb-3">
<button onClick={onClose} className="px-3 py-2 bg-gray-700 text-white rounded">Cancel</button>
{
enableSubmit?<button type="button" className="px-3 py-2 ml-5 bg-green-700 text-white rounded" 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>
}
</div>
</form>
</div>
</div>
</div>
</div>
);
}
\ No newline at end of file
import React, { useState } from "react";
import MyModal from "./index";
export default function ModalButton({type}) {
const [showMyModal, setShowMyModal] = useState(false);
const handleOnClose = () => setShowMyModal(false);
return (
<div className="bg-blue-400 bg-opacity-30">
{/* // <div className="max-w-3xl mx-auto">
// <div className="text-center py-3"> */}
<button
onClick={() => setShowMyModal(true)}
className="bg-red-400 text-white px-3 py-2 rounded hover:scale-95 transition text-xl">
Add Activity
</button>
{/* // </div>
// <p className="text-lg">
// </p>
// </div> */}
<MyModal onClose={handleOnClose} visible={showMyModal} type={type}/>
</div>
);
}
\ No newline at end of file
import React from "react"; import React from "react";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { useParams } from "react-router-dom";
function Sidebar() { function Sidebar() {
const user = useSelector((state) => state.userDetails.user); const user = useSelector((state) => state.userDetails.user);
const reportees = useSelector((state) => state.reportees.reportees);
const url = window.location.href
return ( return (
<div className="w-[30%] flex items-center flex-col"> <div className="w-[30%] flex items-center flex-col px-4">
<div> <div>
<img src="/user.png" width="130px" height="130px" /> <img src="/user.png" width="130px" height="130px" />
</div> </div>
...@@ -12,6 +17,23 @@ function Sidebar() { ...@@ -12,6 +17,23 @@ function Sidebar() {
<p className="text-lg font-semibold">{user.empName}</p> <p className="text-lg font-semibold">{user.empName}</p>
<p>{user.designation}</p> <p>{user.designation}</p>
</div> </div>
{
url.includes('/reports') && <div className="mt-5 border-t-2 border-gray-300 w-[-webkit-fill-available] flex flex-col ">
<p className="text-xl text-blue-400 font-semibold pl-4 mt-3">My Project Allocations</p>
<div className="p-2 bg-[#E9EDEE] mt-4 max-h-[50vh] overflow-auto">
{
reportees?.map(({empName, score, empId}) => (
<div className="flex items-center bg-white p-2 justify-between mb-1" key={empId}>
<img src="/man.png" width="18px" height="18px" />
<p className="w-[80%]">{empName}</p>
<p className="w-[10%] bg-blue-200 rounded-sm text-center">{score}</p>
</div>
))
}
</div>
</div>
}
</div> </div>
); );
} }
......
import React from "react"; import React from "react";
import {Link} from 'react-router-dom';
function Table({headers, data, isView}) { function Table({headers, data, isView}) {
return ( return (
<div class="relative overflow-x-auto shadow-md sm:rounded-lg"> <div className="relative overflow-x-auto shadow-md sm:rounded-lg p-3">
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400"> <table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 bg-transparent justify-center">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"> <thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400 ">
<tr> <tr>
{headers.map((item) => ( {headers.map((item) => (
<th scope="col" class="px-6 py-3 font-bold"> <th scope="col" className="px-6 py-3" >
{item.title} {item.title}
</th> </th>
))} ))}
...@@ -16,9 +17,9 @@ function Table({headers, data, isView}) { ...@@ -16,9 +17,9 @@ function Table({headers, data, isView}) {
<tbody> <tbody>
{ {
data?.map((item, index) => ( data?.map((item, index) => (
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600"> <tr className="bg-white border-b-8 dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
{headers?.map((field) => ( {headers?.map((field) => (
field.id !== "action" ? <td class="px-6 py-4">{item[field.id]}</td> : <td class="px-6 py-4"><button>View</button></td> field.id !== "action" ?<td className="px-6 py-4 listData" >{field.id==="empName"?<span className="flex items-center"><img className="pr-2" src="/user.png" width="30px" height="30px"/>{item[field.id]}</span> :item[field.id]}</td> : <td className="px-6 py-3 border-l-2"><Link to={`/${item.empId}/reports`}><button type="button" className="bg-blue-400 text-white rounded-md px-3 py-1">View</button></Link></td>
))} ))}
</tr> </tr>
......
...@@ -15,3 +15,6 @@ code { ...@@ -15,3 +15,6 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace; monospace;
} }
.listData:nth-child(4) {
padding-left: 35px;
}
\ No newline at end of file
...@@ -10,7 +10,7 @@ function Dashboard() { ...@@ -10,7 +10,7 @@ function Dashboard() {
const reportees = useSelector((state) => state.reportees.reportees); const reportees = useSelector((state) => state.reportees.reportees);
const userDetails = useSelector((state) => state.userDetails); const userDetails = useSelector((state) => state.userDetails);
const { id } = useParams(); const { id } = useParams();
const reporteIds = userDetails.user.reportees || {}; const reporteIds = userDetails.user.reportees || [];
useEffect(() => { useEffect(() => {
if (reporteIds.length > 0) { if (reporteIds.length > 0) {
...@@ -25,11 +25,12 @@ function Dashboard() { ...@@ -25,11 +25,12 @@ function Dashboard() {
}, [reporteIds]); }, [reporteIds]);
useEffect(() => { useEffect(() => {
if(id !== undefined ||null)
dispatch(fetchUser(id)); dispatch(fetchUser(id));
}, []); }, [id]);
const headers = [ const headers = [
{title: "Name", id:"empName"}, {title: "Employee Name", id:"empName"},
{title: "Emp.Id", id: "empId"}, {title: "Emp.Id", id: "empId"},
{title: "Designation", id: 'designation'}, {title: "Designation", id: 'designation'},
{title: "score", id:"score"}, {title: "score", id:"score"},
...@@ -38,7 +39,7 @@ function Dashboard() { ...@@ -38,7 +39,7 @@ function Dashboard() {
] ]
return ( return (
<div> <div>
<Table headers={headers} data={reportees.data} isView={true}/> <Table headers={headers} data={reportees} isView={true}/>
</div> </div>
) )
} }
......
import React, {useState, useEffect} from 'react';
import { useSelector,useDispatch } from 'react-redux';
import { useParams } from 'react-router';
import { fetchReports } from "../../redux/reducers/reportSlice";
import ModalButton from '../../components/modal/modalButton';
function Reports() {
const {id} = useParams();
const dispatch = useDispatch();
const reportees = useSelector((state) => state.reportees.reportees);
const [empDetails, setEmpDetails] = useState(null);
const { report, loading, error}=useSelector((state)=>state.reports)
/*Example post data
{
"empId":41689,
"fromDate":"2024-03-10",
"toDate":"2024-03-11"
}
*/
useEffect(() => {
if(id) {
const emp = reportees?.filter((item) => item.empId === Number(id));
setEmpDetails(emp[0]);
const data = {
"empId":Number(id),
"fromDate":"2024-03-10",
"toDate":"2024-03-15"
}
dispatch(fetchReports(data))
}
return (() => {
setEmpDetails(null)
})
},[id]);
return (
<div>This Perots
<ModalButton type={"default"}/>
</div>
)
}
export default Reports
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { base_url } from "../../utils/constants";
import axios from "axios";
const initialState = {
reports: [],
loading: false,
error: null,
};
export const fetchReports = createAsyncThunk("getReports", async (data) => {
return await axios
.post(`${base_url}/getActivities`, data)
.then((response) => response.data);
});
const reportSlice = createSlice({
name: "reportees",
initialState,
reducers: {
resetReports:() => {
return initialState
}
},
extraReducers: (builder) => {
builder.addCase(fetchReports.pending, (state) => {
state.loading = true;
state.error = "pending";
});
builder.addCase(fetchReports.fulfilled, (state, action) => {
state.loading = false;
state.reports = action.payload?.activities;
state.error = "";
});
builder.addCase(fetchReports.rejected, (state, action) => {
state.loading = false;
state.reports = [];
state.error = action.error || "Something went wrong!";
});
},
});
export const {resetReports} = reportSlice.actions;
export default reportSlice.reducer;
...@@ -15,9 +15,13 @@ export const fetchReportees = createAsyncThunk("getReportees", async (data) => { ...@@ -15,9 +15,13 @@ export const fetchReportees = createAsyncThunk("getReportees", async (data) => {
}); });
const reporteesSlice = createSlice({ const reporteesSlice = createSlice({
name: "counter", name: "reportees",
initialState, initialState,
reducers: {}, reducers: {
resetReportees:() => {
return initialState
}
},
extraReducers: (builder) => { extraReducers: (builder) => {
builder.addCase(fetchReportees.pending, (state) => { builder.addCase(fetchReportees.pending, (state) => {
state.loading = true; state.loading = true;
...@@ -25,7 +29,7 @@ const reporteesSlice = createSlice({ ...@@ -25,7 +29,7 @@ const reporteesSlice = createSlice({
}); });
builder.addCase(fetchReportees.fulfilled, (state, action) => { builder.addCase(fetchReportees.fulfilled, (state, action) => {
state.loading = false; state.loading = false;
state.reportees = action.payload; state.reportees = action.payload.data;
state.error = ""; state.error = "";
}); });
builder.addCase(fetchReportees.rejected, (state, action) => { builder.addCase(fetchReportees.rejected, (state, action) => {
...@@ -36,6 +40,6 @@ const reporteesSlice = createSlice({ ...@@ -36,6 +40,6 @@ const reporteesSlice = createSlice({
}, },
}); });
export const {} = reporteesSlice.actions; export const {resetReportees} = reporteesSlice.actions;
export default reporteesSlice.reducer; export default reporteesSlice.reducer;
import { combineReducers } from 'redux'; import { combineReducers } from 'redux';
import reporteesReducer from './reporteesSlice'; import reporteesReducer from './reporteesSlice';
import userReducer from './userSlice'; import userReducer from './userSlice';
import reportReducer from './reportSlice';
const rootReducer = combineReducers({ const rootReducer = combineReducers({
userDetails: userReducer, userDetails: userReducer,
reportees: reporteesReducer reportees: reporteesReducer,
reports: reportReducer
}); });
export default rootReducer; export default rootReducer;
\ No newline at end of file
...@@ -15,9 +15,13 @@ export const fetchUser = createAsyncThunk("getUser", async (id) => { ...@@ -15,9 +15,13 @@ export const fetchUser = createAsyncThunk("getUser", async (id) => {
}); });
const userSlice = createSlice({ const userSlice = createSlice({
name: "counter", name: "user",
initialState, initialState,
reducers: {}, reducers: {
resetUser:() => {
return initialState
}
},
extraReducers: (builder) => { extraReducers: (builder) => {
// fetch user // fetch user
builder.addCase(fetchUser.pending, (state) => { builder.addCase(fetchUser.pending, (state) => {
...@@ -37,6 +41,6 @@ const userSlice = createSlice({ ...@@ -37,6 +41,6 @@ const userSlice = createSlice({
}, },
}); });
export const {} = userSlice.actions; export const {resetUser} = userSlice.actions;
export default userSlice.reducer; export default userSlice.reducer;
import {resetUser} from '../redux/reducers/userSlice';
import {resetReportees} from '../redux/reducers/reporteesSlice';
const clearStore = (dispatch) => {
dispatch(resetUser());
dispatch(resetReportees());
};
export default clearStore;
\ No newline at end of file
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