Commit eb924f81 authored by Ramadevi Guduri's avatar Ramadevi Guduri

admin reports

parent 6bd4d717
......@@ -7,6 +7,7 @@ import './App.css';
import PageNotFound from './pages/pagenotfound/PageNotFound';
import Exporttable from './pages/reportexport'
import AdminProfile from './pages/adminProfile';
import Adminreports from './pages/adminreports';
function App() {
return (
......@@ -21,7 +22,7 @@ function App() {
<Route path="/viewreportee" element={<Layout><Viewreportee/></Layout>}/>
{/* fetch reports */}
<Route path="/reportees" element={<Layout><Exporttable/></Layout>}/>
<Route path="/adminreportees" element={<Layout><Adminreports/></Layout>}/>
<Route path="/*" element={<PageNotFound/>}/>
</Routes>
......
......@@ -53,6 +53,7 @@ const menus = [
{ title: "Dashboard", path: '/dashboard', selectPaths: ['dashboard'], icon: <DashboardIcon /> },
{ title: "My Reportees", path: '/myreportees', selectPaths: ['myreportees', 'viewreportee'], icon: <ReportsIcon /> },
{ title: "Reports", path: '/reportees', selectPaths:['reportees'], icon: <ReportsIcon /> },
{ title: "Adminreports", path: '/adminreportees', selectPaths:['adminreportees'], icon: <ReportsIcon /> },
]
function Sidebar() {
......
import React, { useEffect, useState } from "react";
import axiosApi from '../../api/axiosConfig';
import { useDispatch, useSelector } from "react-redux";
import { fetchReportesActivitiesData, resetReporteesTableData, resetActivitiesData } from "../../redux/reducers/exporttableslice";
import { fetchReportees } from "../../redux/reducers/reporteesSlice";
import { convertUTCToLocal } from "../../utils/commonFunctions";
import Table from "../../components/table";
import DownloadIcon from '../../assets/icons/downloadIcon';
import jsPDF from 'jspdf';
import 'jspdf-autotable';
import {styles} from './styles';
function Adminreports() {
const dispatch = useDispatch();
const { user } = useSelector((state) => state.userDetails);
const { activitiesData } = useSelector((state) => state.totalreportees);
const { reportees, loading, totalCount, currPage, pagesCount } = useSelector(
(state) => state.reportees
);
const base_url='http://localhost:4000';
const [selectedEmployee, setSelectedEmployee] = useState(0);
const [fromDate, setFromDate] = useState("");
const [toDate, setToDate] = useState("");
const [inputValue, setInputValue] = useState('');
const [pdfLoading, setPdfLoading] = useState(false);
const [selectedDate, setSelectedDate] = useState(null)
useEffect(() => {
if(selectedEmployee && fromDate && toDate) {
let data = {
empId: Number(selectedEmployee),
fromDate: fromDate,
toDate: toDate,
};
dispatch(fetchReportesActivitiesData(data));
}
},[selectedEmployee, fromDate, toDate])
const calculateDateRange = (monthsAgo) => {
const toDate = new Date().toISOString().split("T")[0];
const fromDate = new Date();
fromDate.setMonth(fromDate.getMonth() - monthsAgo);
const fromDateFormatted = fromDate.toISOString().split("T")[0];
return { fromDate: fromDateFormatted, toDate };
};
const handleDropdownChange = (event) => {
const selectedValue = event.target.value;
let fromDate, toDate;
if (selectedValue === "Past 1 month") {
({ fromDate, toDate } = calculateDateRange(1));
} else if (selectedValue === "Past 3 months") {
({ fromDate, toDate } = calculateDateRange(3));
} else if (selectedValue === "Past 6 months") {
({ fromDate, toDate } = calculateDateRange(6));
} else if (selectedValue === "Past 1 year") {
({ fromDate, toDate } = calculateDateRange(12));
}
if(selectedValue!=="")
setSelectedDate(selectedValue)
setFromDate(fromDate);
setToDate(toDate);
};
useEffect(() => {
if (user) {
let data = {
reportees: user.reportees,
page: 1,
perPage: 100000000, //user.reportees.length,
getMasterData: true
};
dispatch(fetchReportees(data));
}
return(() => {
dispatch(resetReporteesTableData())
})
}, []);
const handleReportieDelete = async (id) => {
try {
console.log("Deleting activity with id:", id, "for employee:", selectedEmployee);
await axiosApi.put(`${base_url}/deleteActivity`, { ObjectId: id, empId: Number(selectedEmployee) });
dispatch(fetchReportesActivitiesData({ empId: Number(selectedEmployee), fromDate, toDate }));
} catch (error) {
console.error("Error deleting activity:", id);
console.error("Error:", error);
}
};
const headers = [
{ title: "Activity Name", id: "aName" },
{
title: "Date",
id: "recorded_date",
render: (value) => convertUTCToLocal(value),
},
{ title: "Rated By", id: "ratedBy" },
{
title: "Score",
id: "score",
render: (value) => (
<div className="w-[35px] px-3 bg-blue-400 rounded-full text-white font-bold text-center p-[4px]">
{value}
</div>
),
},
{
title: "Comments",
id: "comments",
render: (value) => (
<span className="listData" title={value}>
{value}
</span>
),
},
{
title: "Delete",
id: "_id",
render: (id) => (
<button
className="bg-red-400 text-white rounded-md px-1 py-1 flex items-center justify-center w-[40px]"
onClick={() => {
if (id && selectedEmployee) {
handleReportieDelete(id,selectedEmployee);
console.log(id)
} else {
console.error("Item or item._id is undefined");
}
}}
>
X
</button>
)
},
];
const periodOptions = ['Past 1 month', 'Past 3 months', 'Past 6 months', 'Past 1 year']
// Function to convert table to PDF
const convertTableToPDF = (data) => {
const doc = new jsPDF({
orientation: 'portrait',
format: 'a4'
});
const headerParams = {
align: 'justify',
fillStyle: 'FD'
}
const tableData = data.map(item => [item.aName, item.ratedBy, item.score, item.comments]);
// Add header to the PDF
doc.text('Score card reports', 15, 10, headerParams);
doc.autoTable({
head: [['Activity Name', 'Rated By', 'Score', 'Comments']], // Extract header row
body: tableData, // Extract data rows
startY: 20, // Start y-position of the table
theme: 'striped', // Table theme: 'plain', 'grid', 'striped', 'striped' (default is 'striped')
styles: { overflow: 'linebreak' }, // Styles for table cells
columnStyles: { 2: { fontStyle: 'bold' } }, // Styles for specific columns
});
// Save PDF
doc.save('ActivitiesList.pdf');
};
const getPdfList = async (type) => {
try{
setPdfLoading(true);
let data = {
empId: Number(selectedEmployee),
fromDate: fromDate,
toDate: toDate,
};
const response = await axiosApi.post(`/getActivities`, data).then((res) => res.data.activities);
if(response.length > 0) convertTableToPDF(response);
} catch {
setPdfLoading(false);
} finally {
setPdfLoading(false);
}
}
const getName = (id) => {
const user = reportees.find((item) => item?.empId === Number(id));
return user ? user.empName : '';
}
const handleSelectedName=(value)=>{
if(value!=="")
setSelectedEmployee(value)
}
return (
<div>
<div className={styles.genarateReportContainer}>
<div className={styles.textBlueHeading}>
REPORTS
</div>
<div>
<form className={styles.formContainer}>
<div className={styles.flexContainer}>
<div className={styles.flexItemsCenter}>
<div className={styles.flexItemsCenter}>
<label htmlFor="countries" className="font-semibold">
SELECT EMPLOYEE:{" "}
</label>
<select
onChange={(e) => handleSelectedName(e.target.value)}
// value={selectedEmployee}
className={styles.selectEmployeeDropdown}
>
<option id="" value="">
Select
</option>
{reportees &&
reportees.map((reportee) => (
<option
className="text-pretty"
key={reportee?.empId}
id={reportee?.empId}
value={reportee?.empId}
>
{reportee?.empName}
</option>
))}
</select>
</div>
<div className={styles.flexItemsCenter}>
<label htmlFor="countries" className="font-semibold ml-4">
SELECT PERIOD:
</label>
<select
onChange={handleDropdownChange}
className={styles.selectEmployeeDropdown && styles.selectDropdown}
>
<option value="">
Select
</option>
{
periodOptions.map((option) => (
<option value={option}>
{option}
</option>
))
}
</select>
</div>
</div>
<div className="flex">
<button
onClick={getPdfList}
disabled={activitiesData?.length === 0}
type="button"
className={styles.downloadButton}
>
<span>{pdfLoading ? "Downloading... " : "Download "} </span>
<DownloadIcon />
{ pdfLoading && <div className="loading ml-2 "></div>}
</button>
</div>
</div>
</form>
</div>
<div className={`mb-4 ${activitiesData?.length === 0 && "hidden"}`}>
<p>Showing <span className="font-semibold">{getName(selectedEmployee)}</span> reports from <span className="font-semibold">{selectedDate}</span> </p>
</div>
<Table headers={headers} loading={loading} data={activitiesData} />
</div>
</div>
);
}
export default Adminreports;
export const styles = {
genarateReportContainer: "overflow-auto sm:rounded-lg p-4 bg-gray-50 ",
textBlueHeading: "text-blue-800 py-3 pl-2 text-center fond-bold text-2xl",
formContainer: "p-2 text-[12px] mb-4",
flexContainer: "flex items-center justify-between",
flexItemsCenter: "flex items-center",
selectEmployeeDropdown:
"bg-gray-50 text-balance rounded-lg rounded-md ml-2 border border-gray-300 text-gray-900 text-sm focus:ring-blue-500 focus:border-blue-500 block p-2.5 ",
selectDropdown:"bg-gray-50 text-balance rounded-lg ml-2 border border-gray-300 text-gray-900 text-sm focus:ring-blue-500 focus:border-blue-500 block p-2.5 w-[235px]",
downloadButton:
"px-3 py-2 ml-5 min-w-[100px] disabled:bg-gray-400 h-[40px] bg-blue-500 font-semibold text-white rounded-md flex items-center justify-center",
Norecords: "text-center align-middle pt-14 pb-14 text-blue-500 font-bold",
};
\ 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