diff --git a/Employee_Managment_App/src/App.tsx b/Employee_Managment_App/src/App.tsx index 87dfc8d..3dff7ae 100644 --- a/Employee_Managment_App/src/App.tsx +++ b/Employee_Managment_App/src/App.tsx @@ -1,5 +1,5 @@ // src/App.tsx -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { BrowserRouter as Router, Routes, Route, NavLink } from 'react-router-dom'; import './App.css'; import TopNav from './components/TopNav'; @@ -8,6 +8,7 @@ import Policies from './components/Policies'; import Achievements from './components/Achievements'; import Organization from './components/Organization'; import EmployeeInfo from './components/EmployeeInfo'; +import { PanelItem } from './components/Announcement'; // Syncfusion Sidebar import { SidebarComponent } from '@syncfusion/ej2-react-navigations'; @@ -45,11 +46,62 @@ function App() { const [sidebarCollapsed, setSidebarCollapsed] = useState(false); // desktop dock const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); // mobile overlay const isDesktop = useMediaQuery('(min-width: 992px)'); + + // Notification items with read status + const [notificationItems, setNotificationItems] = useState([ + { id: 1, title: 'Interview for Customer Support Specialist', subtitle: 'Announcement', date: 'Sep 18', type: 'notification', content: 'You are invited for the Customer Support Specialist interview on Sep 22 at 11:00 AM. Please bring your updated resume and ID.', read: false }, + { id: 2, title: 'Interview for Facilities Executive', subtitle: 'Announcement', date: 'Sep 9', type: 'notification', content: 'Facilities Executive interview is scheduled for Sep 23 at 2:30 PM in Meeting Room A.', read: false }, + { id: 3, title: 'Interview for Office Coordinator / Admin', subtitle: 'Announcement', date: 'Sep 5', type: 'notification', content: 'Your interview for the Office Coordinator / Admin position is scheduled on Sep 25 at 10:00 AM in Conference Room B. Please bring your updated resume and a government-issued ID.', read: false }, + ]); + + const [announcementItems, setAnnouncementItems] = useState([ + { id: 'a1', title: 'Policy Update: Remote Work Guidelines', subtitle: 'Corporate Communication', date: 'Sep 16', type: 'announcement', content: 'We have updated our Remote Work Guidelines effective Oct 1. Key changes include flexible core hours and equipment reimbursement policy. Please read the full policy on the intranet.', read: false }, + { id: 'a2', title: 'Holiday: Office Closed on 2nd Oct', subtitle: 'HR', date: 'Sep 14', type: 'announcement', content: 'In observance of a public holiday, all offices will remain closed on 2nd October. Normal operations resume on 3rd October.', read: false }, + { id: 'a3', title: 'Quarterly Town Hall this Friday', subtitle: 'Admin', date: 'Sep 12', type: 'announcement', content: 'Join us for the Quarterly Town Hall on Sep 20 at 4:00 PM in the Main Auditorium. Leadership will share company updates, upcoming initiatives, and answer your questions. Attendance is encouraged.', read: false }, + ]); useEffect(() => { if (isDesktop) setMobileSidebarOpen(false); }, [isDesktop]); + // Calculate unread counts + const notifications = useMemo(() => ({ + bell: 3, + chat: notificationItems.filter(item => !item.read).length, + tasks: 1, + announcements: announcementItems.filter(item => !item.read).length, + }), [notificationItems, announcementItems]); + + // Handler to mark a single item as read + const handleMarkRead = (itemId: string | number, isNotification: boolean) => { + if (isNotification) { + setNotificationItems((prev) => + prev.map((item) => + item.id === itemId ? { ...item, read: true } : item + ) + ); + } else { + setAnnouncementItems((prev) => + prev.map((item) => + item.id === itemId ? { ...item, read: true } : item + ) + ); + } + }; + + // Handler to mark all as read + const handleMarkAllRead = (tab: 'notifications' | 'announcements') => { + if (tab === 'notifications') { + setNotificationItems((prev) => + prev.map((item) => ({ ...item, read: true })) + ); + } else { + setAnnouncementItems((prev) => + prev.map((item) => ({ ...item, read: true })) + ); + } + }; + const layoutVars: LayoutCSSVars = { '--sidebar-expanded': `${SIDEBAR_WIDTH}px`, '--sidebar-collapsed': `${SIDEBAR_WIDTH_COLLAPSED}px`, @@ -82,7 +134,12 @@ function App() { companyName="NexGen7 Software" userFullName="Test Person" headerOffsetLeft={isDesktop ? (sidebarCollapsed ? SIDEBAR_WIDTH_COLLAPSED : SIDEBAR_WIDTH) : 0} + notifications={notifications} + notificationItems={notificationItems} + announcementItems={announcementItems} onSearch={(q) => console.log('Search:', q)} + onMarkRead={handleMarkRead} + onMarkAllRead={handleMarkAllRead} /> {/* Syncfusion Sidebar */} @@ -90,6 +147,7 @@ function App() { width={`${SIDEBAR_WIDTH}px`} dockSize={`${SIDEBAR_WIDTH_COLLAPSED}px`} enableDock={sbEnableDock} + enableGestures={false} isOpen={sbIsOpen} type={sbType as any} position="Left" diff --git a/Employee_Managment_App/src/components/Achievements.css b/Employee_Managment_App/src/components/Achievements.css index a42730f..7b9d23e 100644 --- a/Employee_Managment_App/src/components/Achievements.css +++ b/Employee_Managment_App/src/components/Achievements.css @@ -34,8 +34,8 @@ body, /* removed decorative radial gradients */ min-height: 100%; color: var(--text); - font-family: Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"; -} + font-family: 'Roboto', sans-serif; + } /* Toolbar - flat */ .achievements-toolbar { @@ -70,7 +70,9 @@ body, } .toolbar-field { - display: grid; + display: flex; + justify-content: center; + align-items: center; gap: 6px; font-size: 12px; color: var(--muted); @@ -78,6 +80,7 @@ body, .field-label { opacity: .9; + font-size: 14px; } /* Syncfusion dropdowns */ @@ -144,7 +147,7 @@ body, .lb-section { background: var(--surface); border: 1px solid var(--border); - border-radius: 10px; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); overflow: hidden; } @@ -153,6 +156,7 @@ body, display: flex; align-items: center; gap: 10px; + height: 70px; padding: 10px 12px; border-bottom: 1px solid var(--border); background: #fff; @@ -171,18 +175,21 @@ body, .bg-r-overall { background: #fb5757; color: #fff; + font-size: 22px; } .icon-task, .bg-r-task { background: #d65e22; color: #fff; + font-size: 22px; } .icon-att, .bg-r-attendance { background: #317701; color: #fff; + font-size: 22px; } .lb-header-text { @@ -196,7 +203,7 @@ body, } .lb-sub { - font-size: 10px; + font-size: 14px; color: #fff; letter-spacing: 1px; padding-top: 5px; @@ -292,13 +299,6 @@ body, font-size: 13px; letter-spacing: .2px; font-feature-settings: "tnum" on, "lnum" on; - background: #f8fafc; padding: 4px 8px; - border-radius: 6px; - border: 1px solid #e5e7eb; font-family: 'Roboto', sans-serif; } - -.score.flat { - background: #f8fafc; -} \ No newline at end of file diff --git a/Employee_Managment_App/src/components/Achievements.tsx b/Employee_Managment_App/src/components/Achievements.tsx index f4cfe2f..d756e03 100644 --- a/Employee_Managment_App/src/components/Achievements.tsx +++ b/Employee_Managment_App/src/components/Achievements.tsx @@ -209,14 +209,14 @@ const Achievements: React.FC = ({ userInfo, onlyTeamIfUser =