Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nisum-scorecard
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Venkaiah Naidu Singamchetty
nisum-scorecard
Commits
e4414a66
Commit
e4414a66
authored
Apr 16, 2024
by
Shiva Komirishetti
Browse files
Options
Browse Files
Download
Plain Diff
menu changes based on role
parents
eb924f81
10a0fed8
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
672 additions
and
105 deletions
+672
-105
db.js
db.js
+1
-1
server.js
server.js
+193
-14
App.js
src/App.js
+2
-0
createActivityButton.jsx
src/components/modal/createActivityButton.jsx
+21
-0
createMyModel.jsx
src/components/modal/createMyModel.jsx
+191
-0
index.jsx
src/components/sidebar/index.jsx
+26
-60
index.jsx
src/components/table/index.jsx
+1
-1
index.js
src/pages/admin/index.js
+98
-0
styles.js
src/pages/admin/styles.js
+6
-0
index.js
src/pages/adminreports/index.js
+32
-22
index.jsx
src/pages/home/index.jsx
+11
-6
activitiesSlice.js
src/redux/reducers/activitiesSlice.js
+82
-0
rootReducer.js
src/redux/reducers/rootReducer.js
+3
-1
commonFunctions.js
src/utils/commonFunctions.js
+5
-0
No files found.
db.js
View file @
e4414a66
...
...
@@ -5,7 +5,7 @@ let dbConnection
module
.
exports
=
{
connectToDb
:
(
cb
)
=>
{
// MongoClient.connect('mongodb://localhost:27017/
ecommerse
')
// MongoClient.connect('mongodb://localhost:27017/
nisum-scorecard
')
MongoClient
.
connect
(
'mongodb+srv://vsingamchetty:user1234@cluster0.ch8kwyt.mongodb.net/nisumscorecard?connectTimeoutMS=30000&socketTimeoutMS=30000'
)
// mongodb+srv://vsingamchetty:user1234@cluster0.ch8kwyt.mongodb.net/
.
then
((
client
)
=>
{
...
...
server.js
View file @
e4414a66
...
...
@@ -62,7 +62,6 @@ app.post('/login', async (req, res) => {
}
});
//to get activities to display
app
.
get
(
"/activities"
,
async
(
req
,
res
)
=>
{
await
db
.
collection
(
"activities_master"
)
...
...
@@ -133,13 +132,13 @@ app.post("/getreportees",async (req, res) => {
.
catch
((
error
)
=>
res
.
status
(
401
).
send
(
error
));
});
//Example of post Data
/*
{
"empId":10000,
"data":{
"aName":"Approval of timesheet",
"aId":"D001",
"type":"duties",
"ratedBy":"Name",
"score":3,
...
...
@@ -156,7 +155,7 @@ app.post('/createActivity',async (req, res) => {
let
{
data
}
=
req
.
body
;
//data validation
if
(
!
_
.
get
(
data
,
"aName"
,
""
)
||
!
_
.
get
(
data
,
"type"
,
""
)
||
!
_
.
get
(
data
,
"score"
,
""
)
||
!
_
.
get
(
data
,
"comments"
,
""
)
||!
_
.
get
(
data
,
"ratedBy"
,
""
)
)
{
if
(
!
_
.
get
(
data
,
"aName"
,
""
)
||
!
_
.
get
(
data
,
"
aId"
,
""
)
||
!
_
.
get
(
data
,
"
type"
,
""
)
||
!
_
.
get
(
data
,
"score"
,
""
)
||
!
_
.
get
(
data
,
"comments"
,
""
)
||!
_
.
get
(
data
,
"ratedBy"
,
""
)
)
{
res
.
status
(
401
).
json
({
"error"
:
"Invalid Activity data"
});
return
;
}
...
...
@@ -372,17 +371,6 @@ app.post("/getActivities-avg", async(req, res) => {
}
});
aggreGate
.
push
({
$project
:{
"type"
:
"$_id"
,
"avgScore"
:
1
}
});
aggreGate
.
push
({
$unset
:
"_id"
});
db
.
collection
(
"performance_master"
)
.
aggregate
(
aggreGate
)
...
...
@@ -393,3 +381,194 @@ app.post("/getActivities-avg", async(req, res) => {
.
catch
((
error
)
=>
res
.
status
(
401
).
send
(
error
));
}
});
// -------------------------------------------------------------
const
checkEmpIdExists
=
async
(
req
,
res
,
next
)
=>
{
try
{
const
empId
=
req
.
body
.
empId
;
const
empEdit
=
req
.
body
?.
empEdit
;
const
reportingTo
=
req
.
body
.
reportingTo
;
const
existingEmployee
=
await
db
.
collection
(
'employees'
).
findOne
({
empId
:
empId
});
if
(
existingEmployee
&&
!
empEdit
)
{
return
res
.
status
(
400
).
json
({
error
:
"Employee already exists"
});
}
else
if
(
!
existingEmployee
){
await
db
.
collection
(
'employees'
).
updateOne
({
empId
:
reportingTo
},
{
$push
:
{
reportees
:
empId
}
});
next
();
}
else
{
db
.
collection
(
'employees'
).
updateOne
({
empId
:
existingEmployee
.
reportingTo
},{
$pull
:
{
reportees
:
{
$eq
:
empId
}
}
});
await
db
.
collection
(
'employees'
).
updateOne
({
empId
:
reportingTo
},
{
$push
:
{
reportees
:
empId
}
});
next
();
}
}
catch
(
error
)
{
console
.
error
(
'Error checking or updating employee data:'
,
error
);
res
.
status
(
500
).
json
({
error
:
"Internal server error"
});
}
};
const
checkEmpIdActivityExists
=
async
(
req
,
res
,
next
)
=>
{
try
{
const
empId
=
req
.
body
.
empId
;
const
existingEmployee
=
await
db
.
collection
(
'performance_master'
).
findOne
({
empId
:
empId
});
if
(
!
existingEmployee
)
{
return
res
.
status
(
400
).
json
({
error
:
"Employee doesn't have any activity"
});
}
else
{
next
();
}
}
catch
(
error
)
{
res
.
status
(
500
).
json
({
error
:
"Internal server error"
});
}
};
// Add employee details API endpoint
// {
// "empId": 41716,
// "empName": "Prashanth vagalaboina",
// "designation": "Software Engineer",
// "reportingTo": 16020,
// "score": 0,
// "project": "prologies",
// "reportees": [],
// "empEmail": "pvagalaboina@nisum.com",
// "techStack": "Frontend",
// "createdBy": 41111,
// "roleId": 1,
// "status": 1,
// "updatedBy": 41111
// }
app
.
post
(
'/addEmployee'
,
checkEmpIdExists
,
async
(
req
,
res
)
=>
{
try
{
const
empData
=
req
.
body
;
// Insert data into MongoDB
const
result
=
await
db
.
collection
(
'employees'
).
insertOne
(
empData
);
res
.
status
(
201
).
json
({
message
:
'Data added successfully'
,
insertedId
:
result
.
insertedId
});
}
catch
(
err
)
{
console
.
error
(
'Error adding data:'
,
err
);
res
.
status
(
500
).
json
({
message
:
'Internal server error'
});
}
});
// Update employee details API endpoint
// Mandatory(*) fields are Editable in UI
// {
// "empId": 41716,
// * "empName": "Prashanth vagalaboina",
// * "designation": "Software Engineer",
// * "reportingTo": 16020,
// "score": 0,
// * "project": "prologies",
// "reportees": [],
// "empEmail": "pvagalaboina@nisum.com",
// * "techStack": "Frontend",
// "createdBy": 41111,
// * "roleId": 1,
// * "status": 1,
// * "updatedBy": 41111,
// "empEdit" : "true"
// }
app
.
put
(
'/updateEmployee'
,
checkEmpIdExists
,
async
(
req
,
res
)
=>
{
try
{
const
{
empId
,
empName
,
project
,
roleId
,
designation
,
status
,
reportingTo
,
techStack
,
updatedBy
}
=
req
.
body
;
// Update employee details
const
result
=
await
db
.
collection
(
'employees'
).
updateOne
(
{
empId
:
empId
},
{
$set
:
{
empName
,
project
,
roleId
,
designation
,
status
,
reportingTo
,
techStack
,
updatedBy
}
}
);
if
(
result
.
modifiedCount
===
1
)
{
res
.
status
(
200
).
json
({
message
:
'Employee details updated successfully'
});
}
else
{
res
.
status
(
404
).
json
({
message
:
'Employee not found'
});
}
}
catch
(
err
)
{
console
.
error
(
'Error updating employee details:'
,
err
);
res
.
status
(
500
).
json
({
message
:
'Internal server error'
});
}
});
// Employee role and status check API endpoint
// {
// "category": "emp_roles" or "emp_status"
// }
app
.
post
(
'/getmaster-data'
,(
req
,
res
)
=>
{
let
emp
=
req
.
body
.
category
;
let
collection
=
""
if
(
emp
===
"emp_roles"
)
collection
=
"emp_roles"
;
if
(
emp
===
"emp_status"
)
collection
=
"emp_status"
;
db
.
collection
(
collection
).
find
({}).
toArray
()
.
then
(
result
=>
{
res
.
status
(
201
).
json
(
result
);
})
.
catch
(
error
=>
res
.
status
(
500
).
json
({
error
:
"Could not fetch the Role / Status of Employee"
}));
});
// Delete Activity details API endpoint
// {
// "empId": 41716,
// "ObjectId": "660ba3ab707f841402133801"
// }
app
.
put
(
'/deleteActivity'
,
checkEmpIdActivityExists
,
async
(
req
,
res
)
=>
{
try
{
const
empId
=
req
.
body
.
empId
;
const
Id
=
req
.
body
.
ObjectId
;
const
result
=
await
db
.
collection
(
'performance_master'
).
updateOne
({
empId
:
empId
},{
$pull
:
{
activities
:
{
_id
:
new
ObjectId
(
Id
)
}
}
});
console
.
log
(
result
);
if
(
result
.
modifiedCount
===
1
)
{
res
.
status
(
200
).
json
({
message
:
'Employee activity deleted successfully'
});
}
}
catch
(
err
)
{
console
.
error
(
'Error updating employee details:'
,
err
);
res
.
status
(
500
).
json
({
message
:
'Internal server error'
});
}
});
// Add MasterActivity details API endpoint
// {
// "atype": "duties",
// "aName": "submission test",
// "appreciate": "true",
// "depreciate": "false"
// }
app
.
post
(
'/addMasterActivity'
,
async
(
req
,
res
)
=>
{
try
{
const
empActivityMasterData
=
req
.
body
;
// Insert data into MongoDB
const
result
=
await
db
.
collection
(
'activities_master'
).
insertOne
(
empActivityMasterData
);
res
.
status
(
201
).
json
({
message
:
'Data added successfully'
,
insertedId
:
result
.
insertedId
});
}
catch
(
err
)
{
console
.
error
(
'Error adding data:'
,
err
);
res
.
status
(
500
).
json
({
message
:
'Internal server error'
});
}
});
// Delete Master Activity details API endpoint
// {
// "ObjectId": "660ba3ab707f841402133801"
// }
app
.
put
(
'/deleteMasterActivity'
,
async
(
req
,
res
)
=>
{
const
aId
=
req
.
body
.
ObjectId
;
await
db
.
collection
(
'activities_master'
).
deleteOne
({
_id
:
new
ObjectId
(
aId
)}).
then
((
result
)
=>
{
res
.
send
(
result
);}).
catch
((
error
)
=>
res
.
status
(
401
).
send
(
error
));
});
\ No newline at end of file
src/App.js
View file @
e4414a66
...
...
@@ -8,6 +8,7 @@ import PageNotFound from './pages/pagenotfound/PageNotFound';
import
Exporttable
from
'./pages/reportexport'
import
AdminProfile
from
'./pages/adminProfile'
;
import
Adminreports
from
'./pages/adminreports'
;
import
Admin
from
'./pages/admin'
;
function
App
()
{
return
(
...
...
@@ -23,6 +24,7 @@ function App() {
{
/* fetch reports */
}
<
Route
path
=
"/reportees"
element
=
{
<
Layout
><
Exporttable
/><
/Layout>}/
>
<
Route
path
=
"/adminreportees"
element
=
{
<
Layout
><
Adminreports
/><
/Layout>}/
>
<
Route
path
=
"/Admin"
element
=
{
<
Layout
><
Admin
/><
/Layout>}/
>
<
Route
path
=
"/*"
element
=
{
<
PageNotFound
/>
}
/
>
<
/Routes
>
...
...
src/components/modal/createActivityButton.jsx
0 → 100644
View file @
e4414a66
import
React
,
{
useState
}
from
"react"
;
import
MyCreateModal
from
"./createMyModel"
;
export
default
function
CreateActivityButton
({
handleRefresh
})
{
const
[
showMyModal
,
setShowMyModal
]
=
useState
(
false
);
return
(
<
div
className=
"bg-blue-400 bg-opacity-30 mr-4"
onClick=
{
(
e
)
=>
e
.
stopPropagation
()
}
>
<
button
className=
"bg-blue-400 text-white px-2 py-2 rounded hover:scale-95 transition text-sm"
onClick=
{
()
=>
setShowMyModal
(
true
)
}
>
Create Activity
</
button
>
{
showMyModal
?<
MyCreateModal
setShowMyModal=
{
setShowMyModal
}
handleRefresh=
{
handleRefresh
}
/>:
null
}
</
div
>
);
}
\ No newline at end of file
src/components/modal/createMyModel.jsx
0 → 100644
View file @
e4414a66
import
React
,
{
useEffect
,
useState
,
useCallback
}
from
"react"
;
import
axios
from
"axios"
;
import
{
base_url
}
from
"../../utils/constants"
;
import
{
fetchData
}
from
"../../pages/admin"
;
const
MyCreateModal
=
({
setShowMyModal
,
handleRefresh
})
=>
{
const
[
formData
,
setFormData
]
=
useState
({
atype
:
""
,
aName
:
""
,
appreciate
:
""
,
depreciate
:
""
,
});
const
[
enableSubmit
,
setEnableSubmit
]
=
useState
(
false
);
const
handleInputChange
=
useCallback
(
(
event
)
=>
{
const
{
name
,
value
}
=
event
.
target
;
setFormData
({
...
formData
,
[
name
]:
value
});
},
[
formData
]
);
const
handleRadioChange
=
useCallback
(
(
event
)
=>
{
const
{
name
,
value
}
=
event
.
target
;
setFormData
({
...
formData
,
[
name
]:
value
===
"true"
});
},
[
formData
]
);
useEffect
(()
=>
{
const
{
atype
,
aName
,
appreciate
,
depreciate
}
=
formData
;
if
(
atype
!==
""
&&
aName
!==
""
&&
(
appreciate
===
true
||
appreciate
===
false
)
&&
(
depreciate
===
true
||
depreciate
===
false
)
)
{
// All conditions met
setEnableSubmit
(
true
);
}
else
{
setEnableSubmit
(
false
);
}
},
[
formData
]);
const
handleSubmit
=
async
(
event
)
=>
{
event
.
preventDefault
();
try
{
// console.log(formData.atype);
await
axios
.
post
(
`
${
base_url
}
/addMasterActivity`
,
formData
)
.
then
((
res
)
=>
fetchData
())
setShowMyModal
(
false
);
setFormData
({
atype
:
""
,
aName
:
""
,
appreciate
:
""
,
depreciate
:
""
,
});
handleRefresh
()
}
catch
(
error
)
{
console
.
error
(
"Error submitting form data:"
,
error
);
}
};
return
(
<
div
className=
"absolute w-full h-full inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex items-center justify-center"
>
<
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"
>
atype Type
</
div
>
<
div
>
<
form
onSubmit=
{
handleSubmit
}
className=
"p-2 max-w-sm mx-auto text-[12px]"
>
<
div
className=
"flex items-center my-5"
>
<
label
htmlFor=
"atype"
>
SELECT atype
<
span
className=
"text-[15px]"
>
*
</
span
>
:
{
" "
}
</
label
>
<
select
id=
"atype"
name=
"atype"
value=
{
formData
.
atype
}
onChange=
{
handleInputChange
}
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"
>
<
option
value=
""
>
Select
</
option
>
<
option
value=
"duties"
>
Duties
</
option
>
<
option
value=
"initiative"
>
Initiative
</
option
>
</
select
>
</
div
>
<
div
className=
"flex items-center"
>
<
label
className=
"font-medium mr-2"
>
atype Name
<
span
className=
"text-[15px]"
>
*
</
span
>
:
</
label
>
<
input
type=
"text"
placeholder=
"Enter atype name"
name=
"aName"
value=
{
formData
.
aName
}
onChange=
{
handleInputChange
}
className=
"border border-gray-300 rounded p-2"
/>
</
div
>
<
div
className=
"flex items-center mb-1"
>
<
label
htmlFor=
"appreciate"
className=
"font-medium"
>
Appreciate
<
span
className=
"text-[15px]"
>
*
</
span
>
:
</
label
>
<
label
htmlFor=
"appreciateTrue"
className=
"font-medium ms-2"
>
True
{
" "
}
</
label
>
<
input
id=
"appreciateTrue"
type=
"radio"
value=
"true"
name=
"appreciate"
checked=
{
formData
.
appreciate
===
true
}
onChange=
{
handleRadioChange
}
className=
"w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300"
/>
<
label
htmlFor=
"appreciateFalse"
className=
"font-medium"
>
False
{
" "
}
</
label
>
<
input
id=
"appreciateFalse"
type=
"radio"
value=
"false"
name=
"appreciate"
checked=
{
formData
.
appreciate
===
false
}
onChange=
{
handleRadioChange
}
className=
"w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300"
/>
</
div
>
<
div
className=
"flex items-center mb-1"
>
<
label
htmlFor=
"depreciate"
className=
"font-medium"
>
Depreciate
<
span
className=
"text-[15px]"
>
*
</
span
>
:
</
label
>
<
label
htmlFor=
"depreciateTrue"
className=
"font-medium ms-2"
>
True
{
" "
}
</
label
>
<
input
id=
"depreciateTrue"
type=
"radio"
value=
"true"
name=
"depreciate"
checked=
{
formData
.
depreciate
===
true
}
onChange=
{
handleRadioChange
}
className=
"w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300"
/>
<
label
htmlFor=
"depreciateFalse"
className=
"font-medium"
>
False
{
" "
}
</
label
>
<
input
id=
"depreciateFalse"
type=
"radio"
value=
"false"
name=
"depreciate"
checked=
{
formData
.
depreciate
===
false
}
onChange=
{
handleRadioChange
}
className=
"w-4 h-4 m-3 text-blue-600 bg-gray-100 border-gray-300"
/>
</
div
>
<
div
className=
"flex items-center justify-end mb-3"
>
<
button
className=
"px-3 py-2 rounded-md bg-gray-700 text-white"
onClick=
{
()
=>
setShowMyModal
(
false
)
}
>
Cancel
</
button
>
<
button
type=
"submit"
className=
{
`px-3 py-2 ml-5 rounded-md ${
enableSubmit
? "bg-blue-500 text-white"
: "bg-gray-400 text-white"
}`
}
disabled=
{
!
enableSubmit
}
title=
"Please fill all fields to submit"
>
Submit
</
button
>
</
div
>
</
form
>
</
div
>
</
div
>
</
div
>
);
};
export
default
MyCreateModal
;
\ No newline at end of file
src/components/sidebar/index.jsx
View file @
e4414a66
// import React from "react";
// import { Link, useParams } from "react-router-dom";
// import SetWindowSize from '../../utils/SetWindowSize';
// import DashboardIcon from '../../assets/icons/dashboardIcon';
// import ReportsIcon from '../../assets/icons/reportsIcon';
// const menus = [
// {title: "Dashboard", path: '/dashboard', selectPaths: ['dashboard', 'viewreportee'], icon: <DashboardIcon/> },
// {title: "Reports", path: '/reportees', selectPaths:['reportees'], icon: <ReportsIcon />}
// ]
// function Sidebar() {
// const url = window.location.href;
// const [windowWidth, windowHeight] = SetWindowSize();
// const selected = url.split('/').at(-1)
// return (
// <div className="w-[20%] flex items-center flex-col overflow-auto" style={{ height: `calc(${windowHeight}px - 87px)` }}>
// <nav
// className="hs-accordion-group p-6 w-full flex flex-col flex-wrap"
// data-hs-accordion-always-open
// >
// <ul className="space-y-1.5">
// {
// menus.map((menu) => (
// <li key={menu.path}>
// <Link
// className={`flex items-center ${menu.selectPaths.includes(selected) && 'bg-gray-100'} gap-x-3.5 py-2 px-2.5 text-sm text-slate-700 rounded-lg hover:bg-gray-100 `}
// to={menu.path}
// >
// <span>{menu.icon}</span>
// {menu.title}
// </Link>
// </li>
// ))
// }
// </ul>
// </nav>
// </div>
// );
// }
// export default Sidebar;
import
React
from
"react"
;
import
{
Link
,
useParams
}
from
"react-router-dom"
;
import
{
useSelector
}
from
'react-redux'
import
SetWindowSize
from
'../../utils/SetWindowSize'
;
import
DashboardIcon
from
'../../assets/icons/dashboardIcon'
;
import
ReportsIcon
from
'../../assets/icons/reportsIcon'
;
import
AdminProfileIcon
from
'../../assets/icons/adminProfileIcon'
;
// Assuming you have an icon for Admin Profile
import
Admin
from
"../../pages/admin"
;
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
/>
},
{
title
:
"Dashboard"
,
path
:
'/dashboard'
,
selectPaths
:
[
'dashboard'
],
icon
:
<
DashboardIcon
/>,
role
:[
2
,
3
]
},
{
title
:
"My Reportees"
,
path
:
'/myreportees'
,
selectPaths
:
[
'myreportees'
,
'viewreportee'
],
icon
:
<
ReportsIcon
/>,
role
:[
2
]
},
{
title
:
"Reports"
,
path
:
'/reportees'
,
selectPaths
:[
'reportees'
],
icon
:
<
ReportsIcon
/>,
role
:[
2
]
},
{
title
:
"Activity List"
,
path
:
'/admin'
,
selectPaths
:[
'admin'
],
icon
:
<
ReportsIcon
/>,
role
:[
1
]
},
{
title
:
"Reports"
,
path
:
'/adminreportees'
,
selectPaths
:[
'adminreportees'
],
icon
:
<
ReportsIcon
/>,
role
:[
1
]
},
]
function
Sidebar
()
{
const
userDetails
=
useSelector
((
state
)
=>
state
.
userDetails
?.
user
);
const
url
=
window
.
location
.
href
;
const
[
windowWidth
,
windowHeight
]
=
SetWindowSize
();
const
selected
=
url
.
split
(
'/'
).
at
(
-
1
)
const
selected
=
url
.
split
(
'/'
).
at
(
-
1
);
const
roleId
=
userDetails
.
roleId
??
0
return
(
<
div
className=
"w-[20%] flex bg-blue-700 text-white items-center flex-col overflow-auto"
style=
{
{
height
:
`calc(${windowHeight}px - 87px)`
}
}
>
...
...
@@ -69,7 +31,9 @@ function Sidebar() {
>
<
ul
className=
"space-y-1.5"
>
{
menus
.
map
((
menu
)
=>
(
menus
.
map
((
menu
)
=>
{
if
(
menu
.
role
.
includes
(
roleId
))
{
return
(
<
li
key=
{
menu
.
path
}
>
<
Link
className=
{
`flex ${menu.selectPaths.includes(selected) && 'bg-blue-500 ' } gap-x-3.5 py-2 lg:px-5 min-sm:px-4 text-sm text-slate-700 hover:bg-blue-500 text-white`
}
...
...
@@ -79,7 +43,9 @@ function Sidebar() {
</
Link
>
</
li
>
))
)
}
})
}
</
ul
>
...
...
src/components/table/index.jsx
View file @
e4414a66
...
...
@@ -83,7 +83,7 @@ function Table({headers, data,loading, handleSorting }) {
<
tr
key=
{
item
.
id
}
className=
"bg-[#eef5ff] font-medium hover:bg-white "
>
{
headers
?.
map
(({
render
,
id
})
=>
(
<
td
className=
"px-6 py-2 "
>
<
td
className=
"px-6 py-2
capitalize
"
>
{
render
?
render
(
item
[
id
])
:
item
[
id
]
===
""
?
"NA"
:
item
[
id
]
}
</
td
>
))
...
...
src/pages/admin/index.js
0 → 100644
View file @
e4414a66
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
{
useSelector
,
useDispatch
}
from
"react-redux"
;
// Import useDispatch
import
CreateActivityButton
from
'../../components/modal/createActivityButton'
;
import
Table
from
'../../components/table'
;
import
Loading
from
"../../components/loading Component/Loading"
;
import
{
styles
}
from
'./styles.js'
;
import
{
convertToString
}
from
"../../utils/commonFunctions"
;
import
axiosApi
from
'../../api/axiosConfig'
// Define fetchData function
export
const
fetchData
=
async
()
=>
{
try
{
const
response
=
await
axiosApi
.
get
(
`/activities`
);
//setActivitiesList(response.data)
return
response
.
data
;
}
catch
(
error
)
{
console
.
error
(
'Error fetching data:'
,
error
);
throw
error
;
// Rethrow the error for handling by the caller if needed
}
};
const
Admin
=
()
=>
{
const
[
activitiesList
,
setActivitiesList
]
=
useState
([]);
const
[
refresh
,
setRefresh
]
=
useState
(
true
)
const
{
loading
}
=
useSelector
((
state
)
=>
state
.
reportees
);
const
dispatch
=
useDispatch
();
// Initialize useDispatch
const
handleRefresh
=
()
=>
{
setRefresh
(
!
refresh
)
}
useEffect
(()
=>
{
// Call fetchData when the component mounts
fetchData
().
then
((
res
)
=>
setActivitiesList
(
res
))
},
[
refresh
]);
const
handleDelete
=
async
(
_id
)
=>
{
try
{
//console.log("Deleting activity with id:", _id);
await
axiosApi
.
put
(
`/deleteMasterActivity`
,
{
ObjectId
:
_id
});
setRefresh
(
!
refresh
)
// console.log("Deleted successfully");
}
catch
(
error
)
{
// console.error("Error deleting activity:", _id);
// console.error("Error:", error);
}
};
const
headers
=
[
{
title
:
"Activity Type"
,
id
:
"atype"
},
{
title
:
"Activity Name"
,
id
:
"aName"
},
{
title
:
"Appreciate"
,
id
:
"appreciate"
,
render
:
(
value
)
=>
convertToString
(
value
)
},
{
title
:
"Depreciate"
,
id
:
"depreciate"
,
render
:
(
value
)
=>
convertToString
(
value
)
},
{
title
:
"Actions"
,
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
)
{
handleDelete
(
id
);
//console.log(id)
}
else
{
// console.error("Item or item._id is undefined");
}
}}
>
X
<
/button
>
)
},
];
if
(
loading
)
return
<
Loading
/>
;
return
(
<
div
>
<
div
className
=
{
styles
.
createActivityContainer
}
>
<
div
className
=
{
styles
.
textBlueHeading
}
>
ACTIVITY
LIST
<
/div
>
<
div
className
=
"flex"
style
=
{{
justifyContent
:
'flex-end'
,
marginBottom
:
"10px"
}}
>
<
CreateActivityButton
handleRefresh
=
{
handleRefresh
}
/
>
<
/div
>
<
Table
headers
=
{
headers
}
loading
=
{
loading
}
data
=
{
activitiesList
}
/
>
<
/div
>
<
/div
>
);
};
export
default
Admin
;
src/pages/admin/styles.js
0 → 100644
View file @
e4414a66
export
const
styles
=
{
createActivityContainer
:
"overflow-auto sm:rounded-lg p-4 bg-[#E9EDEE] "
,
textBlueHeading
:
"text-blue-800 py-3 pl-2 text-center fond-bold text-2xl"
,
};
\ No newline at end of file
src/pages/adminreports/index.js
View file @
e4414a66
...
...
@@ -17,13 +17,13 @@ function Adminreports() {
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
)
const
[
selectedDate
,
setSelectedDate
]
=
useState
(
null
);
const
[
employees
,
setEmployees
]
=
useState
(
null
)
useEffect
(()
=>
{
if
(
selectedEmployee
&&
fromDate
&&
toDate
)
{
...
...
@@ -65,28 +65,39 @@ const base_url='http://localhost:4000';
useEffect
(()
=>
{
if
(
user
)
{
let
data
=
{
reportees
:
user
.
reportees
,
page
:
1
,
perPage
:
100000000
,
//user.reportees.length,
getMasterData
:
true
};
dispatch
(
fetchReportees
(
data
));
// if (user) {
// let data = {
// reportees: user.reportees,
// page: 1,
// perPage: 100000000, //user.reportees.length,
// getMasterData: true
// };
// dispatch(fetchReportees(data));
// }
// return(() => {
// dispatch(resetReporteesTableData())
// })
const
getEmployees
=
async
()
=>
{
try
{
const
res
=
await
axiosApi
.
get
(
`/employees`
);
const
data
=
res
?.
data
.
filter
((
emp
)
=>
emp
.
roleId
!==
1
)
setEmployees
(
data
)
}
catch
(
error
)
{
// console.error("Error:", error);
}
}
return
(()
=>
{
dispatch
(
resetReporteesTableData
())
})
getEmployees
()
},
[]);
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
)
});
await
axiosApi
.
put
(
`/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
);
//
console.error("Error deleting activity:", id);
//
console.error("Error:", error);
}
};
...
...
@@ -117,7 +128,7 @@ const base_url='http://localhost:4000';
),
},
{
title
:
"
Delete
"
,
title
:
"
Actions
"
,
id
:
"_id"
,
render
:
(
id
)
=>
(
<
button
...
...
@@ -125,9 +136,8 @@ const base_url='http://localhost:4000';
onClick
=
{()
=>
{
if
(
id
&&
selectedEmployee
)
{
handleReportieDelete
(
id
,
selectedEmployee
);
console
.
log
(
id
)
}
else
{
console
.
error
(
"Item or item._id is undefined"
);
//
console.error("Item or item._id is undefined");
}
}}
>
...
...
@@ -219,8 +229,8 @@ const base_url='http://localhost:4000';
<
option
id
=
""
value
=
""
>
Select
<
/option
>
{
report
ees
&&
report
ees
.
map
((
reportee
)
=>
(
{
employ
ees
&&
employ
ees
.
map
((
reportee
)
=>
(
<
option
className
=
"text-pretty"
key
=
{
reportee
?.
empId
}
...
...
src/pages/home/index.jsx
View file @
e4414a66
...
...
@@ -40,13 +40,18 @@ function Home() {
setLoading
(
false
)
inputRef
.
current
.
focus
();
},[])
useEffect
(()
=>
{
},[]);
if
(
userDetails
?.
user
!=
null
)
navigate
(
"/dashboard"
)
useEffect
(()
=>
{
if
(
userDetails
?.
user
!=
null
){
if
(
userDetails
?.
user
.
roleId
===
1
)
navigate
(
"/admin"
)
else
navigate
(
"/dashboard"
)
}
else
{
navigate
(
"/"
)
}
},[
userDetails
])
return
(
...
...
src/redux/reducers/activitiesSlice.js
0 → 100644
View file @
e4414a66
import
{
createSlice
,
createAsyncThunk
}
from
"@reduxjs/toolkit"
;
import
axios
from
"axios"
;
export
const
fetchUsers
=
createAsyncThunk
(
"user/fetchUsers"
,
async
()
=>
{
try
{
const
response
=
await
axios
.
get
(
"/addMasterActivity"
);
return
response
.
data
;
}
catch
(
error
)
{
throw
error
;
}
});
export
const
addActivity
=
createAsyncThunk
(
"user/addUser"
,
async
(
values
)
=>
{
try
{
const
response
=
await
axios
.
post
(
"/addMasterActivity"
,
{
type
:
values
.
type
,
aId
:
values
.
aId
,
aId
:
values
.
aId
,
appreciate
:
values
.
appreciate
,
depreciate
:
values
.
depreciate
,
},
{
headers
:
{
Accept
:
"application/json"
,
"Content-Type"
:
"application/json"
,
},
}
);
return
response
.
data
;
}
catch
(
error
)
{
throw
error
;
}
});
const
activitiesSlice
=
createSlice
({
name
:
"activities"
,
initialState
:
{
loading
:
false
,
user
:
[],
error
:
""
,
isSuccess
:
""
,
},
extraReducers
:
(
builder
)
=>
{
builder
.
addCase
(
fetchUsers
.
pending
,
(
state
)
=>
{
state
.
loading
=
true
;
});
builder
.
addCase
(
fetchUsers
.
fulfilled
,
(
state
,
action
)
=>
{
state
.
loading
=
false
;
state
.
user
=
action
.
payload
;
state
.
error
=
""
;
});
builder
.
addCase
(
fetchUsers
.
rejected
,
(
state
,
action
)
=>
{
state
.
loading
=
false
;
state
.
user
=
[];
state
.
error
=
action
.
error
.
message
;
});
builder
.
addCase
(
addActivity
.
pending
,
(
state
)
=>
{
state
.
loading
=
true
;
state
.
error
=
""
;
});
builder
.
addCase
(
addActivity
.
fulfilled
,
(
state
,
action
)
=>
{
state
.
loading
=
false
;
state
.
user
=
[];
state
.
isSuccess
=
action
.
payload
;
});
builder
.
addCase
(
addActivity
.
rejected
,
(
state
,
action
)
=>
{
state
.
loading
=
false
;
state
.
user
=
[];
state
.
error
=
action
.
error
.
message
;
});
},
});
export
default
activitiesSlice
.
reducer
;
src/redux/reducers/rootReducer.js
View file @
e4414a66
...
...
@@ -3,12 +3,14 @@ import reporteesReducer from './reporteesSlice';
import
userReducer
from
'./userSlice'
;
import
reportReducer
from
'./viewreporteeSlice'
;
import
exporttableReducer
from
'./exporttableslice'
;
import
activitiesReducer
from
'./activitiesSlice'
const
rootReducer
=
combineReducers
({
userDetails
:
userReducer
,
reportees
:
reporteesReducer
,
reports
:
reportReducer
,
totalreportees
:
exporttableReducer
totalreportees
:
exporttableReducer
,
activities
:
activitiesReducer
,
});
export
default
rootReducer
;
\ No newline at end of file
src/utils/commonFunctions.js
View file @
e4414a66
...
...
@@ -35,3 +35,8 @@ export const convertUTCToLocal = (utcDate) => {
const
localDateObj
=
new
Date
(
localTimeMillis
);
return
moment
(
localDateObj
).
format
(
'DD-MM-YYYY'
)
}
export
const
convertToString
=
(
value
)
=>
{
return
String
(
value
);
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment