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
4b3e2a6c
Commit
4b3e2a6c
authored
Mar 16, 2024
by
Venkaiah Naidu Singamchetty
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
all-error-handled
parent
e6bc632c
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
142 additions
and
62 deletions
+142
-62
server.js
server.js
+21
-1
App.js
src/App.js
+2
-2
index.jsx
src/components/accordion/index.jsx
+19
-12
DateRangePicker.jsx
src/components/dateRangePicker/DateRangePicker.jsx
+0
-0
index.jsx
src/components/leftSidebar/index.jsx
+6
-3
index.jsx
src/components/sidebar/index.jsx
+12
-12
index.jsx
src/components/table/index.jsx
+4
-3
index.jsx
src/pages/dashboard/index.jsx
+9
-7
index.jsx
src/pages/home/index.jsx
+28
-4
index.jsx
src/pages/layout/index.jsx
+1
-1
index.jsx
src/pages/reports/index.jsx
+26
-7
reportSlice.js
src/redux/reducers/reportSlice.js
+2
-2
reporteesSlice.js
src/redux/reducers/reporteesSlice.js
+2
-3
userSlice.js
src/redux/reducers/userSlice.js
+5
-2
store.js
src/redux/store.js
+5
-3
No files found.
server.js
View file @
4b3e2a6c
...
@@ -43,6 +43,26 @@ app.get("/employee/:id", (req, res) => {
...
@@ -43,6 +43,26 @@ app.get("/employee/:id", (req, res) => {
.
catch
((
error
)
=>
res
.
status
(
401
).
send
(
error
));
.
catch
((
error
)
=>
res
.
status
(
401
).
send
(
error
));
});
});
//login Check
app
.
post
(
'/login'
,
async
(
req
,
res
)
=>
{
const
{
empId
}
=
req
.
body
;
try
{
const
user
=
await
db
.
collection
(
'employees'
).
findOne
({
empId
:
empId
},{
projection
:
{
_id
:
false
}
})
if
(
!
user
)
{
return
res
.
status
(
401
).
json
({
error
:
'Authentication failed'
,
message
:
'User not found'
});
}
if
(
empId
===
user
.
empId
)
{
res
.
json
({
message
:
'Login successful'
,
user
});
}
else
{
res
.
status
(
401
).
json
({
error
:
'Authentication failed'
,
message
:
'Email and password do not match'
});
}
}
catch
(
error
)
{
res
.
status
(
500
).
json
({
error
:
'Internal server error'
,
details
:
error
.
message
});
}
});
//to get activities to display
//to get activities to display
app
.
get
(
"/activities"
,
(
req
,
res
)
=>
{
app
.
get
(
"/activities"
,
(
req
,
res
)
=>
{
db
.
collection
(
"activities_master"
)
db
.
collection
(
"activities_master"
)
...
@@ -186,7 +206,7 @@ const calculateAverage = (query) => {
...
@@ -186,7 +206,7 @@ const calculateAverage = (query) => {
:
(
averageScore
=
score
/
activitiesLength
);
:
(
averageScore
=
score
/
activitiesLength
);
if
(
averageScore
%
1
!==
0
)
{
if
(
averageScore
%
1
!==
0
)
{
averageScore
=
averageScore
.
toFixed
(
1
);
averageScore
=
Number
(
averageScore
)
.
toFixed
(
1
);
}
}
db
.
collection
(
"employees"
)
db
.
collection
(
"employees"
)
...
...
src/App.js
View file @
4b3e2a6c
...
@@ -10,8 +10,8 @@ function App() {
...
@@ -10,8 +10,8 @@ function App() {
<
BrowserRouter
>
<
BrowserRouter
>
<
Routes
>
<
Routes
>
<
Route
path
=
'/'
element
=
{
<
Home
/>
}
/
>
<
Route
path
=
'/'
element
=
{
<
Home
/>
}
/
>
<
Route
path
=
"
:id
/dashboard"
element
=
{
<
Layout
><
Dashboard
/><
/Layout>}/
>
<
Route
path
=
"/dashboard"
element
=
{
<
Layout
><
Dashboard
/><
/Layout>}/
>
<
Route
path
=
"
:id/reports
"
element
=
{
<
Layout
><
Reports
/><
/Layout>}/
>
<
Route
path
=
"
/viewreportee/:id
"
element
=
{
<
Layout
><
Reports
/><
/Layout>}/
>
<
/Routes
>
<
/Routes
>
<
/BrowserRouter
>
<
/BrowserRouter
>
);
);
...
...
src/components/accordion/index.jsx
View file @
4b3e2a6c
...
@@ -4,16 +4,18 @@ import moment from "moment";
...
@@ -4,16 +4,18 @@ import moment from "moment";
import
ModalButton
from
"../modal/modalButton"
;
import
ModalButton
from
"../modal/modalButton"
;
import
{
useSelector
,
useDispatch
}
from
"react-redux"
;
import
{
useSelector
,
useDispatch
}
from
"react-redux"
;
import
{
useEffect
}
from
"react"
;
import
{
useEffect
}
from
"react"
;
import
{
useParams
}
from
'react-router'
import
{
fetchReportees
}
from
"../../redux/reducers/reporteesSlice"
;
import
{
fetchReportees
}
from
"../../redux/reducers/reporteesSlice"
;
import
{
calculateDefaultScore
,
calculateInitiativeScore
}
from
"../../redux/reducers/reportSlice"
;
import
{
calculateDefaultScore
,
calculateInitiativeScore
}
from
"../../redux/reducers/reportSlice"
;
function
Accordion
({
title
,
data
,
handleAddActivity
,
open
,
handleAccordian
})
{
function
Accordion
({
title
,
data
,
handleAddActivity
,
open
,
handleAccordian
})
{
const
dispatch
=
useDispatch
()
const
dispatch
=
useDispatch
()
// const [open, setOpen] = useState(false);
const
{
id
}
=
useParams
()
const
{
reports
,
defaultAvgScore
,
initiativeAvgScore
}
=
useSelector
((
state
)
=>
state
.
reports
);
const
{
reports
,
defaultAvgScore
,
initiativeAvgScore
}
=
useSelector
((
state
)
=>
state
.
reports
);
const
userDetails
=
useSelector
((
state
)
=>
state
.
userDetails
);
const
userDetails
=
useSelector
((
state
)
=>
state
.
userDetails
);
useEffect
(()
=>
{
useEffect
(()
=>
{
const
data
=
{
const
data
=
{
reportees
:
userDetails
.
user
.
reportees
,
reportees
:
userDetails
.
user
.
reportees
,
...
@@ -21,17 +23,21 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
...
@@ -21,17 +23,21 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
page
:
1
,
page
:
1
,
perPage
:
10
,
perPage
:
10
,
}
}
dispatch
(
fetchReportees
(
data
));
dispatch
(
fetchReportees
(
data
))
},[
userDetails
,
id
])
useEffect
(()
=>
{
if
(
reports
!=
[]){
dispatch
(
calculateDefaultScore
(
reports
))
dispatch
(
calculateDefaultScore
(
reports
))
dispatch
(
calculateInitiativeScore
(
reports
))
dispatch
(
calculateInitiativeScore
(
reports
))
}
},[
reports
])
},[
reports
,
id
])
function
handleClick
(){
function
handleClick
(){
handleAccordian
(
title
)
handleAccordian
(
title
)
}
}
const
headers
=
[
const
headers
=
[
{
title
:
"Name"
,
id
:
"aName"
,
width
:
"30%"
},
{
title
:
"
Activity
Name"
,
id
:
"aName"
,
width
:
"30%"
},
{
title
:
"Date"
,
id
:
"recorded_date"
,
width
:
"20%"
,
render
:
(
value
)
=>
moment
(
value
).
format
(
'DD-MM-YYYY'
)
},
{
title
:
"Date"
,
id
:
"recorded_date"
,
width
:
"20%"
,
render
:
(
value
)
=>
moment
(
value
).
format
(
'DD-MM-YYYY'
)
},
{
title
:
"Score"
,
id
:
"score"
,
width
:
"10%"
,
render
:
(
value
)
=>
<
div
className=
"w-[35px] bg-blue-200 rounded-md text-center p-[4px]"
>
{
value
}
</
div
>
},
{
title
:
"Score"
,
id
:
"score"
,
width
:
"10%"
,
render
:
(
value
)
=>
<
div
className=
"w-[35px] bg-blue-200 rounded-md text-center p-[4px]"
>
{
value
}
</
div
>
},
{
title
:
"Comments"
,
id
:
"comments"
,
width
:
"40%"
},
{
title
:
"Comments"
,
id
:
"comments"
,
width
:
"40%"
},
...
@@ -44,15 +50,16 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
...
@@ -44,15 +50,16 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
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 focus:ring-gray-200 dark:focus:ring-gray-800 dark:border-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 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 focus:ring-gray-200 dark:focus:ring-gray-800 dark:border-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 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
>
<
div
className=
"w-1/2 text-start ms-2"
>
{
title
}
</
div
>
<
div
className=
"w-1/2 flex justify-between"
>
Average Score :
{
title
===
"Default Activities:"
?
defaultAvgScore
:
initiativeAvgScore
}
<
div
className=
"w-1/2 flex justify-between"
>
Average Score :
{
title
===
"Default"
?
defaultAvgScore
:
initiativeAvgScore
}
<
ModalButton
type=
{
`${title === "Default" ? "default" : "initiative"}`
}
handleAddActivity=
{
handleAddActivity
}
/>
<
ModalButton
type=
{
`${title === "Default" ? "default" : "initiative"}`
}
handleAddActivity=
{
handleAddActivity
}
/>
</
div
>
</
div
>
<
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"
stroke
-
l
inecap=
"round"
stroke
L
inecap=
"round"
stroke
-
l
inejoin=
"round"
stroke
L
inejoin=
"round"
stroke
-
w
idth=
"2"
stroke
W
idth=
"2"
d=
"M9 5 5 1 1 5"
d=
"M9 5 5 1 1 5"
/>
/>
</
svg
>
</
svg
>
...
...
src/components/DateRangePicker.jsx
→
src/components/
dateRangePicker/
DateRangePicker.jsx
View file @
4b3e2a6c
File moved
src/components/leftSidebar/index.jsx
View file @
4b3e2a6c
import
React
from
"react"
;
import
React
,{
useEffect
,
useState
}
from
"react"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
useSelector
}
from
"react-redux"
;
import
{
useSelector
}
from
"react-redux"
;
import
{
useParams
}
from
"react-router-dom"
;
import
{
useParams
}
from
"react-router-dom"
;
...
@@ -6,6 +6,9 @@ import { useParams } from "react-router-dom";
...
@@ -6,6 +6,9 @@ import { useParams } from "react-router-dom";
function
LeftSidebar
()
{
function
LeftSidebar
()
{
const
reportees
=
useSelector
((
state
)
=>
state
.
reportees
.
reportees
);
const
reportees
=
useSelector
((
state
)
=>
state
.
reportees
.
reportees
);
const
{
id
}
=
useParams
()
const
{
id
}
=
useParams
()
// const [refresh,setRefresh]=useState(false)
// useEffect(()=>{ setRefresh(!refresh)},[reportees])
return
(
return
(
<
div
className=
"mt-2 w-[30%] flex flex-col px-[5px]"
>
<
div
className=
"mt-2 w-[30%] flex flex-col px-[5px]"
>
...
@@ -15,9 +18,9 @@ function LeftSidebar() {
...
@@ -15,9 +18,9 @@ function LeftSidebar() {
<
div
className=
"p-2 bg-[#E9EDEE] mt-4 max-h-[80vh] overflow-auto"
>
<
div
className=
"p-2 bg-[#E9EDEE] mt-4 max-h-[80vh] overflow-auto"
>
{
reportees
?.
map
(({
empName
,
score
,
empId
})
=>
(
{
reportees
?.
map
(({
empName
,
score
,
empId
})
=>
(
<
Link
<
Link
to=
{
`/
${empId}/reports
`
}
to=
{
`/
viewreportee/${empId}
`
}
className=
{
`flex items-center bg-${
className=
{
`flex items-center bg-${
Number(id) === empId ? "
indigo-4
00" : "white"
Number(id) === empId ? "
blue-2
00" : "white"
} p-2 justify-between mb-1 w-full`
}
} p-2 justify-between mb-1 w-full`
}
key=
{
empId
}
key=
{
empId
}
>
>
...
...
src/components/sidebar/index.jsx
View file @
4b3e2a6c
...
@@ -8,26 +8,26 @@ function Sidebar() {
...
@@ -8,26 +8,26 @@ function Sidebar() {
return
(
return
(
<
div
className=
"w-[20%] flex items-center flex-col"
>
<
div
className=
"w-[20%] flex items-center flex-col"
>
<
nav
<
nav
class=
"hs-accordion-group p-6 w-full flex flex-col flex-wrap"
class
Name
=
"hs-accordion-group p-6 w-full flex flex-col flex-wrap"
data
-
hs
-
accordion
-
always
-
open
data
-
hs
-
accordion
-
always
-
open
>
>
<
ul
class=
"space-y-1.5"
>
<
ul
class
Name
=
"space-y-1.5"
>
<
li
>
<
li
>
<
Link
<
Link
class=
{
`flex items-center gap-x-3.5 py-2 px-2.5 bg-gray-100 text-sm text-slate-700 rounded-lg hover:bg-gray-100 dark:bg-gray-900 dark:text-white dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600`
}
class
Name
=
{
`flex items-center gap-x-3.5 py-2 px-2.5 bg-gray-100 text-sm text-slate-700 rounded-lg hover:bg-gray-100 dark:bg-gray-900 dark:text-white dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600`
}
to=
{
`/${user?.empId}/dashboard`
}
to=
{
`/${user?.empId}/dashboard`
}
>
>
<
svg
<
svg
class=
"size-4"
class
Name
=
"size-4"
xmlns=
"http://www.w3.org/2000/svg"
xmlns=
"http://www.w3.org/2000/svg"
width=
"24"
width=
"24"
height=
"24"
height=
"24"
viewBox=
"0 0 24 24"
viewBox=
"0 0 24 24"
fill=
"none"
fill=
"none"
stroke=
"currentColor"
stroke=
"currentColor"
stroke
-
w
idth=
"2"
stroke
W
idth=
"2"
stroke
-
l
inecap=
"round"
stroke
L
inecap=
"round"
stroke
-
l
inejoin=
"round"
stroke
L
inejoin=
"round"
>
>
<
path
d=
"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
/>
<
path
d=
"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
/>
<
polyline
points=
"9 22 9 12 15 12 15 22"
/>
<
polyline
points=
"9 22 9 12 15 12 15 22"
/>
...
@@ -37,19 +37,19 @@ function Sidebar() {
...
@@ -37,19 +37,19 @@ function Sidebar() {
</
li
>
</
li
>
<
li
>
<
li
>
<
Link
<
Link
class=
{
`flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-slate-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-slate-400 dark:hover:text-slate-300 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600`
}
class
Name
=
{
`flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-slate-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-slate-400 dark:hover:text-slate-300 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600`
}
>
>
<
svg
<
svg
class=
"size-4"
class
Name
=
"size-4"
xmlns=
"http://www.w3.org/2000/svg"
xmlns=
"http://www.w3.org/2000/svg"
width=
"24"
width=
"24"
height=
"24"
height=
"24"
viewBox=
"0 0 24 24"
viewBox=
"0 0 24 24"
fill=
"none"
fill=
"none"
stroke=
"currentColor"
stroke=
"currentColor"
stroke
-
w
idth=
"2"
stroke
W
idth=
"2"
stroke
-
l
inecap=
"round"
stroke
L
inecap=
"round"
stroke
-
l
inejoin=
"round"
stroke
L
inejoin=
"round"
>
>
<
path
d=
"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"
/>
<
path
d=
"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"
/>
<
path
d=
"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"
/>
<
path
d=
"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"
/>
...
...
src/components/table/index.jsx
View file @
4b3e2a6c
import
React
from
"react"
;
import
React
from
"react"
;
function
Table
({
headers
,
data
,
maxHeight
})
{
function
Table
({
headers
,
data
,
maxHeight
})
{
return
(
return
(
<
div
className=
{
` overflow-x-auto sm:rounded-lg p-4 max-h-[${maxHeight}vh]`
}
>
<
div
className=
{
` overflow-x-auto sm:rounded-lg p-4 max-h-[${maxHeight}vh]`
}
>
<
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-gray-400 "
>
<
thead
className=
"text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400 "
>
<
tr
className=
"mb-2"
>
<
tr
className=
"mb-2"
>
{
headers
.
map
((
item
)
=>
(
{
headers
.
map
((
item
,
index
)
=>
(
<
th
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
>
))
}
))
}
...
...
src/pages/dashboard/index.jsx
View file @
4b3e2a6c
import
React
,
{
useEffect
}
from
"react"
;
import
React
,
{
useEffect
}
from
"react"
;
import
{
useParams
,
Link
}
from
"react-router-dom"
;
import
{
Link
,
useNavigate
}
from
"react-router-dom"
;
import
{
useDispatch
,
useSelector
}
from
"react-redux"
;
import
{
useDispatch
,
useSelector
}
from
"react-redux"
;
import
{
fetchReportees
}
from
"../../redux/reducers/reporteesSlice"
;
import
{
fetchReportees
}
from
"../../redux/reducers/reporteesSlice"
;
import
{
fetchUser
}
from
"../../redux/reducers/userSlice"
;
import
Table
from
'../../components/table'
;
import
Table
from
'../../components/table'
;
function
Dashboard
()
{
function
Dashboard
()
{
const
dispatch
=
useDispatch
();
const
dispatch
=
useDispatch
();
const
navigate
=
useNavigate
();
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
reporteIds
=
userDetails
.
user
.
reportees
||
[];
const
reporteIds
=
userDetails
.
user
.
reportees
||
[];
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -25,9 +24,12 @@ function Dashboard() {
...
@@ -25,9 +24,12 @@ function Dashboard() {
},
[
reporteIds
]);
},
[
reporteIds
]);
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
id
!==
undefined
||
null
)
if
(
userDetails
.
user
!==
null
){
dispatch
(
fetchUser
(
id
));
navigate
(
"/dashboard"
)
},
[
id
]);
}
else
{
navigate
(
"/"
)
}
},
[
userDetails
]);
const
headers
=
[
const
headers
=
[
{
{
...
@@ -55,7 +57,7 @@ function Dashboard() {
...
@@ -55,7 +57,7 @@ function Dashboard() {
{
{
title
:
"Action"
,
title
:
"Action"
,
id
:
"empId"
,
id
:
"empId"
,
render
:
(
value
)
=>
<
Link
to=
{
`/
${value}/reports
`
}
><
button
className=
"bg-blue-400 text-white rounded-md px-3 py-1"
>
View
</
button
></
Link
>
render
:
(
value
)
=>
<
Link
to=
{
`/
viewreportee/${value}
`
}
><
button
className=
"bg-blue-400 text-white rounded-md px-3 py-1"
>
View
</
button
></
Link
>
},
},
]
]
...
...
src/pages/home/index.jsx
View file @
4b3e2a6c
import
React
,
{
useState
}
from
"react"
;
import
React
,
{
useState
}
from
"react"
;
import
{
useNavigate
}
from
"react-router-dom"
;
import
{
useNavigate
}
from
"react-router-dom"
;
import
axios
from
'axios'
;
import
{
base_url
}
from
"../../utils/constants"
;
import
{
loginUser
}
from
"../../redux/reducers/userSlice"
;
import
{
useDispatch
}
from
'react-redux'
function
Home
()
{
function
Home
()
{
const
navigate
=
useNavigate
();
const
navigate
=
useNavigate
();
const
dispatch
=
useDispatch
()
const
[
id
,
setId
]
=
useState
(
null
);
const
[
id
,
setId
]
=
useState
(
null
);
const
[
errorMsg
,
setErrorMsg
]
=
useState
(
""
)
const
handleNavigate
=
()
=>
{
const
handleNavigate
=
()
=>
{
navigate
(
`
${
id
}
/dashboard`
);
if
(
id
!==
null
){
axios
.
post
(
`
${
base_url
}
/login`
,{
empId
:
Number
(
id
)})
.
then
((
res
)
=>
{
dispatch
(
loginUser
(
res
.
data
.
user
))
navigate
(
`/dashboard`
);
})
.
catch
((
error
)
=>
{
setErrorMsg
(
"Not Authorized"
);
})
}
else
{
navigate
(
`/`
);
}
};
};
return
(
return
(
<
div
className=
"container py-10 px-10 mx-0 min-w-full h-screen flex items-center justify-center bg-blue-100 "
>
<
div
className=
"container py-10 px-10 mx-0 min-w-full h-screen flex items-center justify-center bg-blue-100 "
>
<
div
class=
""
>
<
div
class
Name
=
""
>
<
h1
class=
"text-4xl font-extrabold leading-none tracking-tight md:text-5xl lg:text-6xl text-purple-900 mb-10 "
>
SCORE CARD
</
h1
>
<
h1
class
Name
=
"text-4xl font-extrabold leading-none tracking-tight md:text-5xl lg:text-6xl text-purple-900 mb-10 "
>
SCORE CARD
</
h1
>
<
div
className=
"max-w-sm p-10 bg-white border border-gray-400 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700 "
>
<
div
className=
"max-w-sm p-10 bg-white border border-gray-400 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700 "
>
<
label
<
label
f
or=
"email"
htmlF
or=
"email"
className=
"block mb-2 text-sm font-medium text-gray-900 dark:text-white"
className=
"block mb-2 text-sm font-medium text-gray-900 dark:text-white"
>
>
Employee Id
Employee Id
...
@@ -28,6 +47,11 @@ function Home() {
...
@@ -28,6 +47,11 @@ function Home() {
required
required
onChange=
{
(
e
)
=>
setId
(
e
.
target
.
value
)
}
onChange=
{
(
e
)
=>
setId
(
e
.
target
.
value
)
}
/>
/>
<
div
>
{
errorMsg
!==
""
?
<
span
>
{
errorMsg
}
</
span
>:
null
}
</
div
>
<
button
<
button
className=
"bg-purple-900 text-white disabled:bg-purple-900 hover:bg-blue-400 font-bold py-2 px-4 mt-6 rounded text-center ml-15"
className=
"bg-purple-900 text-white disabled:bg-purple-900 hover:bg-blue-400 font-bold py-2 px-4 mt-6 rounded text-center ml-15"
onClick=
{
handleNavigate
}
onClick=
{
handleNavigate
}
...
...
src/pages/layout/index.jsx
View file @
4b3e2a6c
...
@@ -13,7 +13,7 @@ function Layout({children}) {
...
@@ -13,7 +13,7 @@ function Layout({children}) {
<
div
className=
"bg-[#E9EDEE] w-full"
style=
{
{
height
:
"88vh"
}
}
>
<
div
className=
"bg-[#E9EDEE] w-full"
style=
{
{
height
:
"88vh"
}
}
>
{
children
}
{
children
}
</
div
>
</
div
>
{
url
.
includes
(
'/
reports
'
)
&&
<
LeftSidebar
/>
}
{
url
.
includes
(
'/
viewreportee
'
)
&&
<
LeftSidebar
/>
}
</
div
>
</
div
>
</
div
>
</
div
>
)
)
...
...
src/pages/reports/index.jsx
View file @
4b3e2a6c
...
@@ -4,19 +4,22 @@ import { useParams } from "react-router";
...
@@ -4,19 +4,22 @@ import { useParams } from "react-router";
import
{
base_url
}
from
"../../utils/constants"
;
import
{
base_url
}
from
"../../utils/constants"
;
import
axios
from
'axios'
;
import
axios
from
'axios'
;
import
{
fetchReports
}
from
"../../redux/reducers/reportSlice"
;
import
{
fetchReports
}
from
"../../redux/reducers/reportSlice"
;
import
{
fetchReportees
}
from
"../../redux/reducers/reporteesSlice"
;
import
Accordion
from
"../../components/accordion"
;
import
Accordion
from
"../../components/accordion"
;
import
DateRangePicker
from
"../../components/DateRangePicker"
;
import
DateRangePicker
from
"../../components/
dateRangePicker/
DateRangePicker"
;
function
Reports
()
{
function
Reports
()
{
const
dispatch
=
useDispatch
();
const
{
id
}
=
useParams
();
const
{
id
}
=
useParams
();
const
empId
=
Number
(
id
)
const
empId
=
Number
(
id
)
const
dispatch
=
useDispatch
();
const
reportees
=
useSelector
((
state
)
=>
state
.
reportees
.
reportees
);
const
reportees
=
useSelector
((
state
)
=>
state
.
reportees
.
reportees
);
const
user
=
useSelector
((
state
)
=>
state
.
userDetails
.
user
)
const
[
empDetails
,
setEmpDetails
]
=
useState
(
null
);
const
[
empDetails
,
setEmpDetails
]
=
useState
(
null
);
const
{
reports
}
=
useSelector
((
state
)
=>
state
.
reports
);
const
{
reports
}
=
useSelector
((
state
)
=>
state
.
reports
);
const
[
open
,
setOpen
]
=
useState
({
"accordianOne"
:
true
,
"accordianTwo"
:
false
});
const
[
open
,
setOpen
]
=
useState
({
"accordianOne"
:
true
,
"accordianTwo"
:
false
});
/*Example post data
/*Example post data
{
{
"empId":41689,
"empId":41689,
...
@@ -29,7 +32,7 @@ function Reports() {
...
@@ -29,7 +32,7 @@ function Reports() {
const
filtered
=
Object
.
groupBy
(
reports
,
({
type
})
=>
type
);
const
filtered
=
Object
.
groupBy
(
reports
,
({
type
})
=>
type
);
return
filtered
;
return
filtered
;
}
}
},
[
reports
]);
},
[
reports
,
id
]);
const
handleAccordian
=
(
value
)
=>
{
const
handleAccordian
=
(
value
)
=>
{
switch
(
value
){
switch
(
value
){
...
@@ -48,6 +51,18 @@ function Reports() {
...
@@ -48,6 +51,18 @@ function Reports() {
const
data
=
{
"empId"
:
empId
,
"fromDate"
:
startDate
,
"toDate"
:
endDate
}
const
data
=
{
"empId"
:
empId
,
"fromDate"
:
startDate
,
"toDate"
:
endDate
}
dispatch
(
fetchReports
(
data
))
dispatch
(
fetchReports
(
data
))
}
}
const
fetchLatestReporteesData
=
()
=>
{
if
(
user
){
const
data
=
{
reportees
:
user
.
reportees
,
sort
:
{
type
:
"empId"
,
order
:
1
},
page
:
1
,
perPage
:
10
,
};
dispatch
(
fetchReportees
(
data
));
}
}
const
handleAddActivity
=
(
activityData
)
=>
{
const
handleAddActivity
=
(
activityData
)
=>
{
if
(
id
)
{
if
(
id
)
{
...
@@ -58,6 +73,7 @@ function Reports() {
...
@@ -58,6 +73,7 @@ function Reports() {
axios
.
post
(
`
${
base_url
}
/createActivity`
,
newData
)
axios
.
post
(
`
${
base_url
}
/createActivity`
,
newData
)
.
then
((
result
)
=>
{
.
then
((
result
)
=>
{
getReports
()
getReports
()
fetchLatestReporteesData
()
})
})
}
else
{
}
else
{
alert
(
"Please login"
)
alert
(
"Please login"
)
...
@@ -70,18 +86,21 @@ function Reports() {
...
@@ -70,18 +86,21 @@ function Reports() {
setEmpDetails
(
emp
[
0
]);
setEmpDetails
(
emp
[
0
]);
const
data
=
{
const
data
=
{
"empId"
:
Number
(
id
),
"empId"
:
Number
(
id
),
"fromDate"
:
"
2024-03-10
"
,
"fromDate"
:
""
,
"toDate"
:
"
2024-03-15
"
"toDate"
:
""
}
}
dispatch
(
fetchReports
(
data
))
dispatch
(
fetchReports
(
data
))
}
}
return
(()
=>
{
return
(()
=>
{
setEmpDetails
(
null
)
setEmpDetails
(
null
)
})
})
},
[
id
]);
},
[
id
,
reportees
]);
return
(
return
(
<
div
className=
"p-4"
>
<
div
className=
"p-4"
>
<
div
className=
" bg-white p-3"
>
<
div
className=
" bg-white p-3"
>
<
div
className=
"flex"
>
<
div
className=
"flex"
>
{
/* <img src="/generic-male-avatar-rectangular.jpg" width="100px" height="100px" /> */
}
{
/* <img src="/generic-male-avatar-rectangular.jpg" width="100px" height="100px" /> */
}
...
...
src/redux/reducers/reportSlice.js
View file @
4b3e2a6c
...
@@ -32,8 +32,8 @@ const reportSlice = createSlice({
...
@@ -32,8 +32,8 @@ const reportSlice = createSlice({
calculateInitiativeScore
:(
state
,
action
)
=>
{
calculateInitiativeScore
:(
state
,
action
)
=>
{
const
defaultItems
=
action
.
payload
?.
filter
(
item
=>
item
.
type
===
"initiative"
);
const
defaultItems
=
action
.
payload
?.
filter
(
item
=>
item
.
type
===
"initiative"
);
const
totalDefaultScore
=
defaultItems
?.
reduce
((
acc
,
curr
)
=>
acc
+
curr
.
score
,
0
);
const
totalDefaultScore
=
defaultItems
?.
reduce
((
acc
,
curr
)
=>
acc
+
curr
.
score
,
0
);
const
default
AvgScore
=
totalDefaultScore
>
0
?
totalDefaultScore
/
defaultItems
.
length
:
0
;
const
initial
AvgScore
=
totalDefaultScore
>
0
?
totalDefaultScore
/
defaultItems
.
length
:
0
;
return
{...
state
,
initiativeAvgScore
:
default
AvgScore
.
toFixed
(
1
)}
return
{...
state
,
initiativeAvgScore
:
initial
AvgScore
.
toFixed
(
1
)}
},
},
},
},
...
...
src/redux/reducers/reporteesSlice.js
View file @
4b3e2a6c
...
@@ -8,9 +8,8 @@ const initialState = {
...
@@ -8,9 +8,8 @@ const initialState = {
error
:
null
,
error
:
null
,
};
};
export
const
fetchReportees
=
createAsyncThunk
(
"getReportees"
,
async
(
data
)
=>
{
export
const
fetchReportees
=
createAsyncThunk
(
"getreportees"
,
async
(
data
)
=>
{
return
await
axios
return
await
axios
.
post
(
`
${
base_url
}
/getreportees`
,
data
)
.
post
(
`
${
base_url
}
/getreportees`
,
data
)
.
then
((
response
)
=>
response
.
data
);
.
then
((
response
)
=>
response
.
data
);
});
});
...
...
src/redux/reducers/userSlice.js
View file @
4b3e2a6c
...
@@ -3,7 +3,7 @@ import { base_url } from "../../utils/constants";
...
@@ -3,7 +3,7 @@ import { base_url } from "../../utils/constants";
import
axios
from
"axios"
;
import
axios
from
"axios"
;
const
initialState
=
{
const
initialState
=
{
user
:
{}
,
user
:
null
,
loading
:
false
,
loading
:
false
,
error
:
null
,
error
:
null
,
};
};
...
@@ -20,6 +20,9 @@ const userSlice = createSlice({
...
@@ -20,6 +20,9 @@ const userSlice = createSlice({
reducers
:
{
reducers
:
{
resetUser
:()
=>
{
resetUser
:()
=>
{
return
initialState
return
initialState
},
loginUser
:(
state
,
action
)
=>
{
return
{...
state
,
user
:
action
.
payload
}
}
}
},
},
extraReducers
:
(
builder
)
=>
{
extraReducers
:
(
builder
)
=>
{
...
@@ -41,6 +44,6 @@ const userSlice = createSlice({
...
@@ -41,6 +44,6 @@ const userSlice = createSlice({
},
},
});
});
export
const
{
resetUser
}
=
userSlice
.
actions
;
export
const
{
resetUser
,
loginUser
}
=
userSlice
.
actions
;
export
default
userSlice
.
reducer
;
export
default
userSlice
.
reducer
;
src/redux/store.js
View file @
4b3e2a6c
import
{
configureStore
}
from
'@reduxjs/toolkit'
;
import
{
configureStore
,
Tuple
}
from
'@reduxjs/toolkit'
;
import
rootReducer
from
'./reducers/rootReducer'
;
import
rootReducer
from
'./reducers/rootReducer'
;
import
sessionStorage
from
'redux-persist/es/storage/session'
import
sessionStorage
from
'redux-persist/es/storage/session'
import
{
persistReducer
,
persistStore
}
from
'redux-persist'
;
import
{
persistReducer
,
persistStore
}
from
'redux-persist'
;
import
{
thunk
}
from
'redux-thunk'
const
persistConfig
=
{
const
persistConfig
=
{
...
@@ -12,8 +13,9 @@ const persistConfig={
...
@@ -12,8 +13,9 @@ const persistConfig={
const
persistState
=
persistReducer
(
persistConfig
,
rootReducer
)
const
persistState
=
persistReducer
(
persistConfig
,
rootReducer
)
const
store
=
configureStore
({
const
store
=
configureStore
({
reducer
:
persistState
,
reducer
:
persistState
,
middleware
:()
=>
new
Tuple
(
thunk
)
});
},
);
export
const
persistor
=
persistStore
(
store
);
export
const
persistor
=
persistStore
(
store
);
...
...
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