diff --git a/package-lock.json b/package-lock.json index 9697642..7beadb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "Atlas", - "version": "0.1.0", + "version": "0.1.28", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Atlas", - "version": "0.1.0", + "version": "0.1.28", "dependencies": { "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", diff --git a/src/Adminside/Components/Entrypage.js b/src/Adminside/Components/Entrypage.js index 6c48810..d18ec4a 100644 --- a/src/Adminside/Components/Entrypage.js +++ b/src/Adminside/Components/Entrypage.js @@ -11,10 +11,10 @@ const AtlasRoleSelect = () => { const isMobile = width < 480; const roles = [ - { label: "Employee", icon: , path: "/employeelogin" }, - { label: "Manager", icon: , path: "/managerlogin" }, - { label: "Human Resource", icon: , path: "/hrlogin" }, - { label: "Administrator", icon: , path: "/login" }, + { label: "Employee", icon: , path: "/employeelogin" }, + { label: "Manager", icon: , path: "/managerlogin" }, + { label: "Human Resource", icon: , path: "/hrlogin" }, + { label: "Administrator", icon: , path: "/login" }, ]; /* ── Mobile layout — single column stacked cards ── */ @@ -22,9 +22,12 @@ const AtlasRoleSelect = () => { return (
-
- Atlas logo + Atlas logo

Aτλας

Access your workspace

@@ -56,9 +59,12 @@ const AtlasRoleSelect = () => { return (
-
- Atlas logo + Atlas logo

Aτλας

Access your workspace

@@ -80,7 +86,9 @@ const AtlasRoleSelect = () => { ))}
-
© 2025-26 Powered by NoCapCode Infrastructure.
+
+ © 2025-26 Powered by NoCapCode Infrastructure. +
); @@ -90,12 +98,14 @@ const AtlasRoleSelect = () => { return (
-
-

Welcome to Aτλας Workspace

+

+ Welcome to Aτλας Workspace +

- Select your functional portal to access the workspace
environments designed for your role. + Select your functional portal to access the workspace
+ environments designed for your role.

  • ✓ Secure authentication
  • @@ -105,28 +115,64 @@ const AtlasRoleSelect = () => {
- navigate("/employeelogin")}> -
+ navigate("/employeelogin")} + > +
+ +

Employee

-

Access your personal dashboard, pay stubs, benefits, and training modules.

+

+ Access your personal dashboard, pay stubs, benefits, and + training modules. +

- navigate("/managerlogin")}> -
+ navigate("/managerlogin")} + > +
+ +

Manager

-

Review team performance metrics, approve requests, and manage talent pipelines.

+

+ Review team performance metrics, approve requests, and manage + talent pipelines. +

- navigate("/hrlogin")}> -
+ navigate("/hrlogin")} + > +
+ +

Human Resource

-

Administer company-wide policies, recruitment cycles, and employee relations.

+

+ Administer company-wide policies, recruitment cycles, and + employee relations. +

- navigate("/login")}> -
+ navigate("/login")} + > +
+ +

Administrator

-

Full system overrides, configuration management, and security auditing logs.

+

+ Full system overrides, configuration management, and security + auditing logs. +

diff --git a/src/App.js b/src/App.js index c325024..8ac60ef 100644 --- a/src/App.js +++ b/src/App.js @@ -36,6 +36,9 @@ import EmployeeDetails from "./Adminside/Components/EmployeeDetailspage"; import EmployeeProfile from "./Employee Side/Components/EmployeeProfile"; import ManagerLogin from "./Managerside/components/ManagerLogin"; import HRLogin from "./hrside/Components/HRLogin"; +import HRNavbar from "./hrside/Components/HRNavbar"; +import HRDashboard from "./hrside/Components/HRDashboard"; +import { SidebarProvider } from "./hrside/Components/SidebarContext"; import Manager from "./Adminside/Components/Manager"; import Activity from "./Adminside/Components/Activity"; @@ -45,10 +48,11 @@ function Layout({ children }) { const hideNavbarRoutes = ["/","/login","/employeelogin","/managerlogin","/hrlogin"]; const hideNavbar = hideNavbarRoutes.includes(location.pathname); + const isHRRoute = location.pathname.startsWith("/hr/"); return ( <> - {!hideNavbar && } + {!hideNavbar && (isHRRoute ? : )} {children} ); @@ -58,6 +62,7 @@ function Layout({ children }) { function App() { return ( <> + @@ -101,17 +106,15 @@ function App() { {/* hr */} } /> + } /> + ); } -export default App; - - - - \ No newline at end of file +export default App; \ No newline at end of file diff --git a/src/hrside/CSS/hrdashboard.module.css b/src/hrside/CSS/hrdashboard.module.css new file mode 100644 index 0000000..8070d44 --- /dev/null +++ b/src/hrside/CSS/hrdashboard.module.css @@ -0,0 +1,1128 @@ +@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600&display=swap"); +.mainContainer { + background: #050505; + width: 100%; + padding: 28px 50px; + box-sizing: border-box; +} + +.topcontainer { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; + gap: 12px; +} + +.topleft { + display: flex; + flex-direction: column; + gap: 4px; +} + +.topleft1 { + color: #ddddff; + font-family: "Outfit", sans-serif; + font-size: 32px; + font-weight: 600; + line-height: 40px; + letter-spacing: -0.32px; +} + +.topleft2 { + color: #c3c6d6; + font-size: 15px; +} + +.topright { + display: flex; + align-items: center; + gap: 12px; +} + +.topright1 { + padding: 10px 15px; + background-color: #0050b8; + color: #ddddff; + border: 1px solid #6d78ff; + font-weight: 400; + font-size: 13.3px; + border-radius: 8px; + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; +} + +/* ── New: HR dashboard stat cards ── */ +.cards { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 16px; + width: 100%; + max-width: 100%; + margin-bottom: 24px; +} + +@media screen and (max-width: 1200px) { + .cards { + grid-template-columns: repeat(2, 1fr); + } +} + +@media screen and (max-width: 768px) { + .cards { + grid-template-columns: repeat(2, 1fr); + } +} + +@media screen and (max-width: 480px) { + .cards { + grid-template-columns: repeat(1, 1fr); + } + .mainContainer { + padding: 20px 16px; + } +} + +.card { + background: #0e0f13; + border: 1px solid #23262d; + border-radius: 14px; + padding: 20px; + min-height: 90px; + transition: + transform 0.25s ease, + box-shadow 0.25s ease; +} + +.card:hover { + transform: translateY(-4px); + box-shadow: 0 14px 32px rgba(0, 0, 0, 0.3); +} + +.cardTopRow { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 18px; +} + +.cardIcon { + color: #ddddff; +} + +.cardChange { + display: flex; + align-items: center; + gap: 4px; + color: #22c55e; + font-size: 12px; + font-weight: 500; +} + +.cardTitle { + color: #ffffff; + font-size: 13px; + margin-bottom: 8px; +} + +.cardValue { + color: #ffffff; + font-size: 24px; + font-weight: 600; + margin-bottom: 6px; +} + +.cardSubtitle { + color: #ffffff; + font-size: 12px; +} + +@media (max-width: 768px) { + .topcontainer { + flex-direction: column; + align-items: flex-start; + } +} +/* ── Organizational Health + Pulse Sentiment row ── */ +.healthRow { + display: flex; + flex-wrap: wrap; + gap: 24px; + margin-top: 4px; +} + +.healthCard { + flex: 2; +} + +.pulseCard { + flex: 1; +} + +@media screen and (max-width: 900px) { + .healthCard, + .pulseCard { + flex: 1 1 100%; + } +} + +.healthCard, +.pulseCard { + background: #0e0f13; + border: 1px solid #23262d; + border-radius: 14px; + padding: 20px; +} + +/* Organizational Health */ +.healthCardHeader { + display: flex; + justify-content: space-between; + align-items: flex-start; + padding-bottom: 24px; + border-bottom: 1px solid rgba(160, 160, 160, 0.3); + margin-bottom: 24px; +} + +.healthTitle { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 20px; + line-height: 28px; + color: #e1e2ec; +} + +.healthSubtitle { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.6px; + color: #c3c6d6; + margin-top: 2px; +} + +.healthIcon { + color: #0056d2; +} + +.healthStats { + display: flex; + align-items: flex-end; + gap: 32px; + flex-wrap: wrap; +} + +.statBlock { + display: flex; + flex-direction: column; + gap: 8px; +} + +.statNumberBlue { + font-family: "Outfit", sans-serif; + font-weight: 700; + font-size: 40px; + line-height: 40px; + letter-spacing: -0.8px; + color: #0056d2; +} + +.statPercentSign { + font-size: 24px; + font-weight: 600; +} + +.statNumberRed { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 32px; + line-height: 32px; + letter-spacing: -0.32px; + color: #ff5447; +} + +.statLabel { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.6px; + color: #c3c6d6; +} + +.statDivider { + width: 1px; + height: 48px; + background: rgba(160, 160, 160, 0.3); +} + +.trendBlock { + display: flex; + flex-direction: column; + gap: 8px; + flex: 1; + min-width: 120px; +} + +.trendLabel { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.6px; + color: #c3c6d6; +} + +.trendBars { + display: flex; + align-items: flex-end; + gap: 4px; + height: 32px; + opacity: 0.9; +} + +.trendBar { + flex: 1; + background: #484949; + border-radius: 2px 2px 0 0; +} + +.trendBarActive { + flex: 1; + background: #0056d2; + border-radius: 2px 2px 0 0; +} + +/* Pulse Sentiment */ +.pulseHeader { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 8px; + border-bottom: 1px solid rgba(160, 160, 160, 0.3); + margin-bottom: 16px; +} + +.pulseTitle { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 16px; + line-height: 24px; + color: #e1e2ec; +} + +.pulseIcon { + color: #c3c6d6; +} + +.pulseRows { + display: flex; + flex-direction: column; + gap: 16px; +} + +.pulseRow { + display: flex; + flex-direction: column; + gap: 8px; +} + +.pulseTopLine { + display: flex; + justify-content: space-between; + align-items: center; +} + +.pulseLabelWrap { + display: flex; + align-items: center; + gap: 12px; +} + +.pulseDotBlue, +.pulseDotGrey, +.pulseDotRed { + width: 8px; + height: 8px; + border-radius: 12px; + flex-shrink: 0; +} + +.pulseDotBlue { + background: #0056d2; +} + +.pulseDotGrey { + background: #484949; +} + +.pulseDotRed { + background: #ff5447; +} + +.pulseLabel { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.6px; + color: #e1e2ec; +} + +.pulsePercent { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.6px; + color: #c3c6d6; +} + +.pulseBarTrack { + width: 100%; + height: 6px; + background: #191b23; + border: 1px solid rgba(160, 160, 160, 0.1); + border-radius: 12px; + overflow: hidden; +} + +.pulseBarFillBlue, +.pulseBarFillGrey, +.pulseBarFillRed { + height: 100%; + border-radius: 12px; +} + +.pulseBarFillBlue { + background: #0056d2; +} + +.pulseBarFillGrey { + background: #484949; +} + +.pulseBarFillRed { + background: #ff5447; +} +/* ── Ops row: Action Center / Leaves & Exits / Doc Verification ── */ +.opsRow { + display: flex; + flex-wrap: wrap; + gap: 24px; + margin-top: 24px; +} + +.actionCard { + flex: 1.2; +} + +.leavesCard, +.docCard { + flex: 1; +} + +@media screen and (max-width: 900px) { + .actionCard, + .leavesCard, + .docCard { + flex: 1 1 100%; + } +} + +.actionCard, +.leavesCard, +.docCard { + background: #0e0f13; + border: 1px solid #23262d; + border-radius: 14px; + padding: 20px; +} + +/* Action Center */ +.actionHeader { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 16px; +} + +.actionHeaderLeft { + display: flex; + align-items: center; + gap: 8px; +} + +.actionHeaderIcon { + color: #ff5447; +} + +.actionHeaderTitle { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 16px; + color: #e1e2ec; +} + +.viewAllLink { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + color: #6d78ff; + cursor: pointer; +} + +.actionList { + display: flex; + flex-direction: column; + gap: 12px; +} + +.actionItem { + display: flex; + gap: 10px; + padding: 14px 16px; + border-radius: 10px; + background: #191b23; + border: 1px solid transparent; +} + +.actionItemRed { + border-color: #ff5447; + background: #191b23; +} + +.actionItemOrange { + border-color: #ffb020; + background: #191b23; +} + +.actionItemBlue { + border-color: #0056d2; + background: #191b23; +} + +.actionItemIconRed { + color: #ff5447; + flex-shrink: 0; + margin-top: 2px; +} + +.actionItemIconOrange { + color: #ffb020; + flex-shrink: 0; + margin-top: 2px; +} + +.actionItemIconBlue { + color: #0056d2; + flex-shrink: 0; + margin-top: 2px; +} + +.actionItemBody { + flex: 1; +} + +.actionItemTopRow { + display: flex; + justify-content: space-between; + align-items: center; + gap: 8px; +} + +.actionItemTitle { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 13px; + color: #e1e2ec; +} + +.actionBadge { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + flex-shrink: 0; + cursor: pointer; +} + +.actionBadgeRed { + color: #6d78ff; + background: transparent; +} + +.actionBadgeOrange { + color: #ffb020; + background: transparent; +} + +.actionBadgeBlue { + color: #6d9bff; + background: transparent; +} + +.actionItemText { + font-family: "Outfit", sans-serif; + font-weight: 400; + font-size: 12px; + line-height: 1.4; + color: #94a3b8; + margin-top: 4px; +} + +/* Leaves & Exits */ +.leavesHeader { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 16px; + color: #e1e2ec; + padding-bottom: 12px; + border-bottom: 1px solid rgba(160, 160, 160, 0.3); + margin-bottom: 16px; +} + +.leavesBlock { + text-align: center; + padding: 12px 0; +} + +.leavesNumber { + font-family: "Outfit", sans-serif; + font-weight: 700; + font-size: 36px; + color: #ffffff; +} + +.exitsNumber { + font-family: "Outfit", sans-serif; + font-weight: 700; + font-size: 28px; + color: #ff5447; +} + +.leavesLabel { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 11px; + letter-spacing: 0.6px; + color: #94a3b8; + margin-top: 4px; +} + +.leavesDivider { + height: 1px; + background: rgba(160, 160, 160, 0.3); + margin: 4px 0; +} + +.processExitsBtn { + width: 100%; + margin-top: 16px; + padding: 10px; + background: transparent; + color: #6d9bff; + border: 1px solid #0056d2; + border-radius: 8px; + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 13px; + cursor: pointer; + transition: background 0.2s ease; +} + +.processExitsBtn:hover { + background: rgba(0, 86, 210, 0.1); +} + +/* Doc Verification */ +.docHeader { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 16px; + color: #e1e2ec; + padding-bottom: 12px; + border-bottom: 1px solid rgba(160, 160, 160, 0.3); + margin-bottom: 16px; +} + +.docList { + display: flex; + flex-direction: column; + gap: 10px; +} + +.docRow { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 14px; + background: rgba(160, 160, 160, 0.05); + border: 1px solid transparent; + border-radius: 8px; +} + +.docRowAlert { + border-color: #ff5447; + background: rgba(255, 84, 71, 0.06); +} + +.docLabel { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 13px; + color: #e1e2ec; +} + +.docValue { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 13px; + color: #e1e2ec; +} + +.docValueGreen { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 13px; + color: #22c55e; +} + +.docValueRed { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 13px; + color: #ff5447; +} + +.reviewQueueBtn { + width: 100%; + margin-top: 16px; + padding: 10px; + background: transparent; + color: #e1e2ec; + border: 1px solid #23262d; + border-radius: 8px; + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 13px; + cursor: pointer; + transition: background 0.2s ease; +} + +.reviewQueueBtn:hover { + background: rgba(160, 160, 160, 0.08); +} +/* ── Pipeline row: Onboarding / Payroll Cycle / Ticket Overview ── */ +.pipelineRow { + display: flex; + flex-wrap: wrap; + gap: 24px; + margin-top: 24px; +} + +.pipelineCard { + flex: 1.6; +} + +.payrollCard, +.ticketCard { + flex: 1; +} + +@media screen and (max-width: 900px) { + .pipelineCard, + .payrollCard, + .ticketCard { + flex: 1 1 100%; + } +} + +.pipelineCard, +.payrollCard, +.ticketCard { + background: #0e0f13; + border: 1px solid #23262d; + border-radius: 14px; + padding: 20px; +} + +/* Onboarding Pipeline */ +.pipelineHeader { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 10px; + padding-bottom: 12px; + border-bottom: 1px solid rgba(160, 160, 160, 0.3); + margin-bottom: 20px; +} + +.pipelineTitle { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 18px; + color: #e1e2ec; +} + +.pipelineLegend { + display: flex; + gap: 14px; + flex-wrap: wrap; +} + +.legendItem { + display: flex; + align-items: center; + gap: 6px; + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + color: #c3c6d6; +} + +.legendDotGrey, +.legendDotBlue { + width: 8px; + height: 8px; + border-radius: 50%; +} + +.legendDotGrey { + background: #484949; +} + +.legendDotBlue { + background: #0056d2; +} + +.legendDotOutline { + width: 8px; + height: 8px; + border-radius: 50%; + border: 1.5px solid #c3c6d6; +} + +.pipelineList { + display: flex; + flex-direction: column; + gap: 20px; +} + +.pipelineDept { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 13px; + color: #e1e2ec; + margin-bottom: 8px; +} + +.pipelineBarTrack { + width: 100%; + height: 8px; + background: #23262d; + border-radius: 12px; + overflow: hidden; +} + +.pipelineBarFill { + height: 100%; + background: #0056d2; + border-radius: 12px; +} + +/* Payroll Cycle */ +.payrollCard { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.payrollHeader { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding-bottom: 12px; + border-bottom: 1px solid rgba(160, 160, 160, 0.3); + margin-bottom: 20px; +} + +.payrollTitle { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 16px; + color: #e1e2ec; +} + +.payrollIcon { + color: #c3c6d6; +} + +.payrollRingWrap { + position: relative; + width: 120px; + height: 120px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 16px; +} + +.payrollPercentLabel { + position: absolute; + font-family: "Outfit", sans-serif; + font-weight: 700; + font-size: 28px; + color: #ffffff; +} + +.payrollProcessed { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 13px; + color: #e1e2ec; + margin-bottom: 8px; +} + +.payrollMeta { + font-family: "Outfit", sans-serif; + font-weight: 400; + font-size: 12px; + color: #94a3b8; +} + +.viewBatchBtn { + width: 100%; + margin-top: 16px; + padding: 10px; + background: transparent; + color: #e1e2ec; + border: 1px solid #23262d; + border-radius: 8px; + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 13px; + cursor: pointer; + transition: background 0.2s ease; +} + +.viewBatchBtn:hover { + background: rgba(160, 160, 160, 0.08); +} + +/* Ticket Overview */ +.ticketHeader { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 12px; + border-bottom: 1px solid rgba(160, 160, 160, 0.3); + margin-bottom: 16px; +} + +.ticketTitle { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 16px; + color: #e1e2ec; +} + +.ticketHeaderIcon { + color: #c3c6d6; +} + +.ticketList { + display: flex; + flex-direction: column; + gap: 10px; +} + +.ticketRow { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 14px; + background: #15171d; + border-left: 3px solid transparent; + border-radius: 8px; +} + +.ticketRowBlue { + border-left-color: #0056d2; + background: rgba(0, 86, 210, 0.06); +} + +.ticketRowRed { + border-left-color: #ff5447; + background: rgba(255, 84, 71, 0.06); +} + +.ticketLabelWrap { + display: flex; + align-items: center; + gap: 8px; +} + +.ticketIconGrey { + color: #94a3b8; +} + +.ticketIconBlue { + color: #0056d2; +} + +.ticketIconRed { + color: #ffb020; +} + +.ticketLabel { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 13px; + color: #e1e2ec; +} + +.ticketValue { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 13px; + color: #e1e2ec; +} + +.ticketValueBlue { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 13px; + color: #6d9bff; +} + +.ticketValueRed { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 13px; + color: #ff5447; +} +/* ── Performance Risk Monitor ── */ +.riskCard { + background: #0e0f13; + border: 1px solid #23262d; + border-radius: 14px; + padding: 20px; + margin-top: 24px; +} + +.riskHeader { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 12px; + border-bottom: 1px solid rgba(160, 160, 160, 0.3); + margin-bottom: 20px; +} + +.riskHeaderLeft { + display: flex; + align-items: center; + gap: 8px; +} + +.riskHeaderIcon { + color: #e1e2ec; +} + +.riskTitle { + font-family: "Outfit", sans-serif; + font-weight: 600; + font-size: 16px; + color: #e1e2ec; +} + +.riskPeriod { + font-family: "Outfit", sans-serif; + font-weight: 500; + font-size: 12px; + color: #94a3b8; +} + +.riskGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; +} + +@media screen and (max-width: 900px) { + .riskGrid { + grid-template-columns: 1fr; + } +} + +.riskTile { + background: #191b23; + border: 1px solid rgba(160, 160, 160, 0.1); + border-radius: 4px; + padding: 16px; +} + +.riskTileLabel { + display: flex; + align-items: center; + gap: 6px; + font-family: "Outfit", sans-serif; + font-weight: 700; + font-size: 11px; + letter-spacing: 0.6px; + color: #ff5447; + margin-bottom: 14px; +} + +.riskTileLabelGreen { + color: #22c55e; +} + +.riskTileRow { + display: flex; + justify-content: space-between; + align-items: baseline; +} + +.riskTileValue { + font-family: "Outfit", sans-serif; + font-weight: 700; + font-size: 28px; + color: #ffffff; +} + +.riskTileUnit { + font-family: "Outfit", sans-serif; + font-weight: 400; + font-size: 12px; + color: #94a3b8; +} + +.riskTileDivider { + height: 1px; + background: rgba(160, 160, 160, 0.15); + margin: 12px 0; +} + +.riskTileNote { + font-family: "Outfit", sans-serif; + font-weight: 400; + font-size: 11.5px; + color: #94a3b8; +} +.actionIconBadgeRed { + width: 28px; + height: 28px; + border-radius: 6px; + background: rgba(255, 84, 71, 0.14); + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} diff --git a/src/hrside/CSS/navbar.module.css b/src/hrside/CSS/navbar.module.css new file mode 100644 index 0000000..745ffdb --- /dev/null +++ b/src/hrside/CSS/navbar.module.css @@ -0,0 +1,560 @@ +.container { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 35px; + background-color: #0E0F13; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + position: sticky; + top: 0; + z-index: 10; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); +} + +.logo{ + cursor: pointer; + color: #ffffff; + display: flex; + align-items: center; + justify-content: center; +} + +.logoImg { + width: 32px; + height: 32px; + object-fit: contain; + border-radius: 6px; + transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); + transform: rotate(0deg); +} + +.logoRotated { + transform: rotate(90deg); +} + +.notification { + cursor: pointer; + padding: 0 16px; + border-right: 1px solid rgba(255, 255, 255, 0.15); + color: #d1d5db; + display: flex; + align-items: center; + transition: color 0.2s ease; +} + +.notification:hover { + color: #ffffff; +} + +.profile { + display: flex; + position: relative; + align-items: center; + gap: 12px; + cursor: pointer; + color: #ffffff; + padding-left: 6px; + user-select: none; +} + +.right { + display: flex; + align-items: center; + gap: 16px; +} + +.profilepic { + width: 36px; + height: 36px; + border-radius: 50%; + overflow: hidden; + background-color: #2b2b52; + color: #6d64fa; + display: flex; + justify-content: center; + align-items: center; + font-weight: 600; +} + +.profileName { + font-size: 15px; + font-weight: 500; +} + +.profileChevron { + transition: transform 0.3s ease; + opacity: 0.7; +} + +.info { + position: absolute; + top: calc(100% + 14px); + right: 0; + width: 160px; + background: #1c212d; + border: 1px solid #2a3142; + border-radius: 12px; + padding: 6px; + display: flex; + flex-direction: column; + gap: 2px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); + z-index: 100; + transform-origin: top right; + animation: dropdownPop 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards; +} + +.options { + display: flex !important; + align-items: center !important; + gap: 12px !important; + background: transparent !important; + border: none !important; + box-shadow: none !important; + padding: 10px 14px !important; + color: #d1d5db !important; + font-weight: 500 !important; + text-align: left !important; + cursor: pointer !important; + border-radius: 8px !important; + font-size: 14px !important; + transition: all 0.2s ease !important; + width: 100% !important; +} + +.options:hover { + background: rgba(109, 100, 250, 0.15) !important; + color: #ffffff !important; +} + +.menuScroll { + flex: 1; + overflow-y: auto; + padding: 12px 0 30px; + min-height: 0; +} + +.logomenu{ + width:100%; + display:flex; + padding: 20px 30px; + gap:75px; + align-items: center; + justify-content: center; + color: #ffffff; +} + +.reportsDropdown { + display: none; + flex-direction: column; + align-self: end; + border-left: 0.85px solid #A5A5A5; +} + +.showDropdown { + display: flex; + width:80%; +} + +.reportItem { + width:90%; + color: #e2e8f0; + padding: 10px 16px; + margin: 6px 0; + cursor: pointer; + font-size: 14px; + transition: all 0.3s ease; +} + +.reportItem:hover { + background: #6366f1; + color:white; + transform: translateX(4px); +} + +.sidebarOverlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.6); + z-index: 19; +} + +.mobilemenu { + position: relative; + width: 300px; + height: 100vh; + background: #0F0F0F; + border-right: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + flex-direction: column; +} + +.dashboardmenu{ + display:flex; + align-items: center; + padding: 10px 30px; + gap:15px; + font-weight: 400; + font-size: 15px; + width: 95%; + margin: 0 auto; + color: #94a3b8; + cursor: pointer; + transition: all 0.3s ease; + border-radius: 10px; +} + +.dashboardmenu:hover { + background-color: rgba(99, 102, 241, 0.1); + color: #e2e8f0; +} + +.dashboardmenucolor{ + display:flex; + width:80%; + align-items: center; + justify-content: center; + margin: 0 auto; + color:white; + cursor:pointer; + border-radius: 10px; + padding: 10px 30px; + gap:15px; + font-weight: 400; + font-size: 15px; + background-color: #0050B8; + box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3); +} + +.employeeInfo { + display: flex; + align-items: center; + gap: 12px; + padding-right: 20px; + border-right: 1px solid rgba(255, 255, 255, 0.1); +} + +.userText h2 { + font-size: 16px; + font-weight: 600; + color: #ffffff; + margin: 0; +} + +.userMeta { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + color: #94a3b8; + margin-top: 4px; +} + +.statususer { + display: flex; + align-items: center; + gap: 6px; + padding: 4px 10px; + border-radius: 12px; + font-size: 12px; + font-weight: 500; +} + +.PUNCH_IN { background-color: rgba(34, 197, 94, 0.15); color: #22c55e; } +.BREAK { background-color: rgba(251, 146, 60, 0.15); color: #fb923c; } +.PUNCH_OUT { background-color: rgba(148, 163, 184, 0.15); color: #94a3b8; } + +.onlineDot { + width: 6px; height: 6px; + border-radius: 50%; + background-color: #22c55e; + animation: pulse 2s infinite; +} + +.breakDot { + width: 6px; height: 6px; + border-radius: 50%; + background-color: #fb923c; +} + +.endDot { + width: 6px; height: 6px; + border-radius: 50%; + background-color: #94a3b8; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +.sep { color: rgba(255, 255, 255, 0.2); } + +.timerBoxWrapper { + position: relative; + margin-right: 20px; +} + +.timerBox { + display: flex; + align-items: center; + gap: 14px; + padding: 6px 14px 6px 6px; + background: #13151c; + border: 1px solid #232836; + border-radius: 12px; + cursor: pointer; + transition: all 0.2s ease; + user-select: none; +} + +.timerBox:hover { + background: #181b24; + border-color: #2e3547; +} + +.playPauseBtn { + background: #2b2b52; + border: none; + border-radius: 10px; + padding: 10px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: #6d64fa; + transition: all 0.3s ease; +} + +.playPauseBtn:hover { + background: #353566; +} + +.timerTextWrap { + display: flex; + flex-direction: column; + justify-content: center; +} + +.timerLabel { + font-size: 10px; + font-weight: 600; + color: #6E768F; + margin: 0 0 2px 0; + text-transform: uppercase; + letter-spacing: 0.8px; +} + +.timerValue { + font-size: 15px; + color: #ffffff; + font-weight: 700; + font-family: 'Courier New', Courier, monospace; + letter-spacing: 2.5px; +} + +.chevron { + transition: transform 0.3s ease; + margin-left: 4px; + opacity: 0.8; +} + +.timerDropdown { + position: absolute; + top: calc(100% + 6px); + left: 0; + right: 0; + width: 100%; + background: #1c212d; + border: 1px solid #2a3142; + border-radius: 12px; + padding: 6px; + display: flex; + flex-direction: column; + gap: 2px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); + z-index: 100; + transform-origin: top center; + animation: dropdownPop 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards; +} + +.timerDropdown button { + display: flex !important; + align-items: center !important; + gap: 12px !important; + background: transparent !important; + border: none !important; + box-shadow: none !important; + padding: 10px 12px !important; + color: #d1d5db !important; + font-weight: 500 !important; + text-align: left !important; + cursor: pointer !important; + border-radius: 8px !important; + font-size: 13px !important; + transition: all 0.2s ease !important; + width: 100% !important; +} + +.timerDropdown button:hover { + background: rgba(109, 100, 250, 0.15) !important; + color: #ffffff !important; +} + +@keyframes dropdownPop { + 0% { + opacity: 0; + transform: translateY(-8px) scaleY(0.95); + } + 100% { + opacity: 1; + transform: translateY(0) scaleY(1); + } +} + +@media (max-width: 1024px) { + .employeeInfo { + display: none; + } + + .timerBoxWrapper { + margin-right: 10px; + } + + .timerBox { + padding: 6px 12px; + gap: 8px; + } + + .timerLabel { + font-size: 10px; + } + + .timerValue { + font-size: 14px; + } +} + +@media (max-width: 768px) { + .searchInput { + min-width: 100px; + width: 70%; + } + + .container { + padding: 10px 16px; + } + + .notification { + padding: 0 8px; + border-right: 2px solid rgba(255, 255, 255, 0.1); + } + + .employeeInfo { + display: none; + } + + .timerBoxWrapper { + margin-right: 6px; + } + + .timerBox { + padding: 4px 8px 4px 4px !important; + gap: 8px !important; + border-radius: 10px; + } + + .timerLabel { + display: none !important; + } + + .timerValue { + font-size: 13px !important; + letter-spacing: 1px; + } + + .playPauseBtn { + padding: 8px !important; + border-radius: 8px; + } + + .playPauseBtn svg { + width: 14px !important; + height: 14px !important; + } + + .timerBox > svg { + width: 14px !important; + height: 14px !important; + } + + .profile span { + display: none; + } + + .right { + gap: 6px; + } +} + +.menuFooter { + display: flex; + flex-direction: column; + gap: 2px; + padding: 12px 0 20px; + border-top: 1px solid rgba(255, 255, 255, 0.1); +} + +@media (max-width: 480px) { + .container { + padding: 8px 12px; + } + + .notification { + padding: 0 6px; + border-right: none; + } + + .profilepic { + width: 30px; + height: 30px; + font-size: 12px; + } + + .timerBoxWrapper { + margin-right: 4px; + } + + .timerBox { + padding: 5px 8px !important; + gap: 5px !important; + border-radius: 8px; + } + + .timerLabel { + display: none !important; + } + + .timerValue { + font-size: 12px !important; + } + + .playPauseBtn { + padding: 4px !important; + border-radius: 5px; + } + + .playPauseBtn svg { + width: 12px !important; + height: 12px !important; + } + + .timerBox > svg { + width: 12px !important; + height: 12px !important; + } + + .right { + gap: 5px; + } +} \ No newline at end of file diff --git a/src/hrside/Components/HRDashboard.js b/src/hrside/Components/HRDashboard.js new file mode 100644 index 0000000..8378cca --- /dev/null +++ b/src/hrside/Components/HRDashboard.js @@ -0,0 +1,605 @@ +import React from "react"; +import styles from "../CSS/hrdashboard.module.css"; + +import { + Users, + UserPlus, + CreditCard, + CheckCircle2, + TrendingUp, + Download, + Smile, + AlertTriangle, + ShieldAlert, + Clock, + UserCog, + Inbox, + Loader2, + Gauge, + TrendingDown, + Flag, + BatteryLow, +} from "lucide-react"; + +function HRDashboard() { + const pipeline = [ + { dept: "Engineering (12)", percent: 65 }, + { dept: "Sales (8)", percent: 75 }, + { dept: "Operations (5)", percent: 90 }, + ]; + + const payrollPercent = 82; + const radius = 45; + const circumference = 2 * Math.PI * radius; + const payrollOffset = circumference * (1 - payrollPercent / 100); + + const cards = [ + { + icon: , + change: "+4.5%", + title: "Total Active Employees", + value: "1,248", + subtitle: "Total workforce count", + }, + { + icon: , + change: "+4.5%", + title: "New Joinees", + value: "32", + subtitle: "Joined this month", + }, + { + icon: , + change: "+4.5%", + title: "Payroll Pending", + value: "$45k", + subtitle: "3 approvals remaining", + }, + { + icon: ( + + + + + ), + change: "+4.5%", + title: "Onboarding Completion", + value: "87%", + subtitle: "Average across depts", + }, + ]; + + return ( +
+
+
+
Dashboard
+
+ Real-time HR operations and organizational health. +
+
+
+
+ + Export Report +
+
+
+ +
+ {cards.map((card, i) => ( +
+
+
{card.icon}
+
+ + {card.change} +
+
+
{card.title}
+
{card.value}
+
{card.subtitle}
+
+ ))} +
+ +
+ {/* Organizational Health */} +
+
+
+
Organizational Health
+
Last 30 days
+
+ + + +
+ +
+
+
+ 85% +
+
Employee Satisfaction
+
+ +
+ +
+
4
+
Open Grievances
+
+ +
+ +
+
Attrition Trend (-1.2%)
+
+ + + + + +
+
+
+
+ + {/* Pulse Sentiment */} +
+
+
Pulse Sentiment
+ +
+ +
+
+
+
+ + Positive +
+ 65% +
+
+
+
+
+ +
+
+
+ + Neutral +
+ 25% +
+
+
+
+
+ +
+
+
+ + Negative +
+ 10% +
+
+
+
+
+
+
+
+ +
+ {/* Action Center */} +
+
+
+ + Action Center +
+ View All +
+ +
+
+
+ + + +
+
+
+ + Compliance Escalation + + + Review + +
+

+ I-9 verification delayed for 3 new hires in EU region. +

+
+
+ +
+ +
+
+ + SLA Breach Warning + + + Assign + +
+

+ 4 payroll tickets nearing 48h limit. +

+
+
+ +
+ +
+
+ + Onboarding Stalled + + + Nudge + +
+

+ 2 hires haven't completed day-1 tasks. +

+
+
+
+
+ + {/* Leaves & Exits */} +
+
Leaves & Exits
+ +
+
12
+
ACTIVE LEAVES
+
+ +
+ +
+
3
+
PENDING EXITS
+
+ + +
+ + {/* Doc Verification */} +
+
Doc Verification
+ +
+
+ Pending + 18 +
+
+ Approved (Today) + 42 +
+
+ Re-upload Req. + 5 +
+
+ + +
+
+ +
+ {/* Onboarding Pipeline */} +
+
+ Onboarding Pipeline +
+ + Pending + + + In Progress + + + Completed + +
+
+ +
+ {pipeline.map((p, i) => ( +
+
{p.dept}
+
+
+
+
+ ))} +
+
+ + {/* Payroll Cycle */} +
+
+ Payroll Cycle + + + +
+ +
+ + + + +
{payrollPercent}%
+
+ +
Processed
+
Total: $1.2M
+
Scheduled: Tomorrow
+ + +
+ + {/* Ticket Overview */} +
+
+ Ticket Overview + + + +
+ +
+
+
+ + + + Open +
+ 45 +
+ +
+
+ + + + In Progress +
+ 12 +
+ +
+
+ + SLA Risk +
+ 4 +
+
+
+
+ +
+
+
+ + Performance Risk Monitor +
+ Last 90 Days +
+ +
+
+
+ + BELOW THRESHOLD +
+
+ 8 + Employees +
+
+
+ Requires PIP review within 14 days. +
+
+ +
+
+ + + + BEHAVIORAL FLAGS +
+
+ 3 + Incidents +
+
+
+ Peer review anomalies detected. +
+
+ +
+
+ + + + INACTIVITY / BURNOUT +
+
+ 15% + Of Workforce +
+
+
+ Showing sustained low activity levels. +
+
+
+
+
+ ); +} + +export default HRDashboard; diff --git a/src/hrside/Components/HRNavbar.js b/src/hrside/Components/HRNavbar.js new file mode 100644 index 0000000..a136137 --- /dev/null +++ b/src/hrside/Components/HRNavbar.js @@ -0,0 +1,306 @@ +import React, { useState } from "react"; +import styles from "../CSS/navbar.module.css"; +import { + Headphones, + UserCircle, + Settings, + LogOut, +} from "lucide-react"; +import { useNavigate, useLocation } from "react-router-dom"; + +// Custom Home icon +const HomeIcon = ({ size = 20 }) => ( + + + +); + +// Custom People icon +const PeopleIcon = ({ size = 20 }) => ( + + + +); + +// Custom Briefcase icon +const BriefcaseIcon = ({ size = 20 }) => ( + + + +); + +// Custom Documents icon +const DocumentsIcon = ({ size = 20 }) => ( + + + +); + +// Custom Documents and Payroll icon +const DocumentsPayrollIcon = ({ size = 20 }) => ( + + + +); + +function HRNavbar() { + const [menuopen, setMenuopen] = useState(false); + const navigate = useNavigate(); + const location = useLocation(); + const [info, setinfo] = useState(false); + const profileDropdownRef = React.useRef(null); + + const getActive = (path) => location.pathname === path; + + React.useEffect(() => { + const handleClickOutside = (event) => { + if ( + profileDropdownRef.current && + !profileDropdownRef.current.contains(event.target) + ) { + setinfo(false); + } + }; + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, []); + + const handlelogout = () => { + navigate("/hrlogin"); + }; + + const handlesidebar = () => { + setMenuopen(!menuopen); + }; + + return ( + <> +
+
+ + + +
+ +
+
setinfo(!info)} + > +
H
+ + {info && ( +
+ + + +
+ )} +
+
+
+ + {menuopen && ( +
setMenuopen(false)} + > +
e.stopPropagation()} + > +
+
+ + + +
+
+
+
{ + navigate("/hr/dashboard"); + setMenuopen(false); + }} + > + + Home +
+ +
{ + navigate("/hr/employees"); + setMenuopen(false); + }} + > + + People +
+ +
{ + navigate("/hr/attendance"); + setMenuopen(false); + }} + > + + Hiring +
+ +
{ + navigate("/hr/payroll"); + setMenuopen(false); + }} + > + + Onboarding +
+ +
{ + navigate("/hr/payroll-reports"); + setMenuopen(false); + }} + > + + Documents and Payroll +
+
+ +
+
{ + navigate("/hr/support"); + setMenuopen(false); + }} + > + + Support +
+ +
{ + navigate("/hr/admin-profile"); + setMenuopen(false); + }} + > + + Admin Profile +
+
+
+
+ )} + + ); +} + +export default HRNavbar; \ No newline at end of file diff --git a/src/hrside/Components/SidebarContext.js b/src/hrside/Components/SidebarContext.js new file mode 100644 index 0000000..197867f --- /dev/null +++ b/src/hrside/Components/SidebarContext.js @@ -0,0 +1,17 @@ + +import React, { createContext, useContext, useState } from "react"; + +const SidebarContext = createContext(); + +export function SidebarProvider({ children }) { + const [collapsed, setCollapsed] = useState(true); + return ( + + {children} + + ); +} + +export function useSidebar() { + return useContext(SidebarContext); +} \ No newline at end of file