Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Employee_Managment_App/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ function App() {
width={`${SIDEBAR_WIDTH}px`}
dockSize={`${SIDEBAR_WIDTH_COLLAPSED}px`}
enableDock={sbEnableDock}
enableGestures={false}
isOpen={sbIsOpen}
type={sbType as any}
position="Left"
Expand Down
24 changes: 12 additions & 12 deletions Employee_Managment_App/src/components/Achievements.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -70,14 +70,17 @@ body,
}

.toolbar-field {
display: grid;
display: flex;
justify-content: center;
align-items: center;
gap: 6px;
font-size: 12px;
color: var(--muted);
}

.field-label {
opacity: .9;
font-size: 14px;
}

/* Syncfusion dropdowns */
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand All @@ -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 {
Expand All @@ -196,7 +203,7 @@ body,
}

.lb-sub {
font-size: 10px;
font-size: 14px;
color: #fff;
letter-spacing: 1px;
padding-top: 5px;
Expand Down Expand Up @@ -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;
}
21 changes: 7 additions & 14 deletions Employee_Managment_App/src/components/Achievements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,14 @@ const Achievements: React.FC<AchievementsProps> = ({ userInfo, onlyTeamIfUser =

<div className="toolbar-right">
<label className="toolbar-field">
<span className="field-label">Role</span>
<span className="field-label" >Role</span>
<DropDownListComponent
id="role-ddl"
cssClass="sf-field-input"
dataSource={roles}
fields={{ text: 'text', value: 'value' }}
value={role}
width="180px"
width="135px"
placeholder="Select role"
change={(e: any) => setRole(e.value)}
aria-label="Filter by role"
Expand All @@ -231,6 +231,7 @@ const Achievements: React.FC<AchievementsProps> = ({ userInfo, onlyTeamIfUser =
id="month-ddl"
cssClass="sf-field-input"
dataSource={months}
width="100px"
fields={{ text: 'text', value: 'value' }}
value={month}
placeholder="Select month"
Expand All @@ -247,6 +248,7 @@ const Achievements: React.FC<AchievementsProps> = ({ userInfo, onlyTeamIfUser =
id="year-ddl"
cssClass="sf-field-input"
dataSource={years}
width="100px"
fields={{ text: 'text', value: 'value' }}
value={year}
placeholder="Select year"
Expand All @@ -270,10 +272,7 @@ const Achievements: React.FC<AchievementsProps> = ({ userInfo, onlyTeamIfUser =
<div className="lb-sections">
<section className="lb-section">
<header className="lb-header bg-r-overall">
<div className="lb-header-icon icon-overall" aria-hidden>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path d="M7 10a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm10 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM12 9a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm-7 8v-1a4 4 0 0 1 4-4h2a4 4 0 0 1 4 4v1H5zm10 0v-1a5 5 0 0 1 5-5h.5A1.5 1.5 0 0 1 22 12.5V17H15z" />
</svg>
<div className="lb-header-icon icon-overall e-icons e-user" aria-hidden>
</div>
<div className="lb-header-text">
<div className="lb-title">Overall</div>
Expand All @@ -297,10 +296,7 @@ const Achievements: React.FC<AchievementsProps> = ({ userInfo, onlyTeamIfUser =

<section className="lb-section">
<header className="lb-header bg-r-task">
<div className="lb-header-icon icon-task" aria-hidden>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path d="M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
</svg>
<div className="lb-header-icon icon-task e-icons e-check-tick" aria-hidden>
</div>
<div className="lb-header-text">
<div className="lb-title">Task</div>
Expand All @@ -324,10 +320,7 @@ const Achievements: React.FC<AchievementsProps> = ({ userInfo, onlyTeamIfUser =

<section className="lb-section">
<header className="lb-header bg-r-attendance">
<div className="lb-header-icon icon-att" aria-hidden>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path d="M19 3h-1V1h-2v2H8V1H6v2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm0 16H5V8h14v11z" />
</svg>
<div className="lb-header-icon icon-att e-icons e-day" aria-hidden>
</div>
<div className="lb-header-text">
<div className="lb-title">Attendance</div>
Expand Down
80 changes: 52 additions & 28 deletions Employee_Managment_App/src/components/Announcement.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// src/components/Announcement.tsx
// Reusable right-side drawer that shows Notifications and Announcements
// Adds Syncfusion Dialog for item details

import React from 'react';
import './Announcement.css';
import { AnnouncementDetailDialog } from './AnnouncementDetailDialog';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';

export type PanelItem = {
id: string | number;
Expand All @@ -14,6 +14,7 @@ export type PanelItem = {
type?: 'announcement' | 'notification' | 'message';
content?: string; // full body to show in dialog
read?: boolean; // optional read flag
iconClass?: string;
};

export type AnnouncementPanelProps = {
Expand Down Expand Up @@ -51,7 +52,9 @@ export const AnnouncementPanel: React.FC<AnnouncementPanelProps> = ({
}, [open, defaultTab]);

React.useEffect(() => {
const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };
const onKey = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
document.addEventListener('keydown', onKey);
return () => document.removeEventListener('keydown', onKey);
}, [onClose]);
Expand Down Expand Up @@ -80,6 +83,22 @@ export const AnnouncementPanel: React.FC<AnnouncementPanelProps> = ({
setSelectedItem(null);
};

const handleMarkAllRead = () => {
// Notify parent (if provided)
onMarkAllRead?.(tab);

// Keep your existing badge-hiding logic (targets TopNav icon buttons)
const selector =
tab === 'announcements'
? '.icon-btn.e-icons.e-audio span'
: '.icon-btn.e-icons.e-multiple-comment span';
document.querySelectorAll(selector).forEach((el) => {
const span = el as HTMLElement;
span.style.display = 'none';
span.setAttribute('aria-hidden', 'true');
});
};

const items = tab === 'notifications' ? notificationItems : announcementItems;

return (
Expand All @@ -98,31 +117,43 @@ export const AnnouncementPanel: React.FC<AnnouncementPanelProps> = ({
>
<div className="annc-panel-header">
<div className="annc-panel-title">Notification</div>
<button className="annc-panel-close" type="button" aria-label="Close" onClick={onClose} title="Close">
<ButtonComponent
className="annc-panel-close"
cssClass="annc-panel-close"
type="button"
aria-label="Close"
onClick={onClose}
title="Close"
>
<svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
<path fill="currentColor" d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
<path
fill="currentColor"
d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
/>
</svg>
</button>
</ButtonComponent>
</div>

<div className="annc-panel-tabs" role="tablist" aria-label="Notification categories">
<button role="tab" aria-selected={tab === 'notifications'} className={tab === 'notifications' ? 'active' : ''} onClick={() => setActiveTab('notifications')} title="Notifications">
<svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
<path fill="currentColor" d="M12 22a2 2 0 0 0 2-2h-4a2 2 0 0 0 2 2zm6-6V11a6 6 0 1 0-12 0v5l-2 2v1h16v-1l-2-2z" />
</svg>
<button role="tab" aria-selected={tab === 'notifications'} className={tab === 'notifications' ? 'active e-icons e-multiple-comment' : 'e-icons e-multiple-comment'} onClick={() => setActiveTab('notifications')} title="Notifications">
</button>
<button role="tab" aria-selected={tab === 'announcements'} className={tab === 'announcements' ? 'active' : ''} onClick={() => setActiveTab('announcements')} title="Announcements">
<svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
<path fill="currentColor" d="M3 10v4a1 1 0 0 0 1 1h1l3.89 2.6a2 2 0 0 0 3.11-1.65V7.05A2 2 0 0 0 8.89 5.4L5 8H4a1 1 0 0 0-1 1zm18-4v12l-8-4V10l8-4z" />
</svg>
<button role="tab" aria-selected={tab === 'announcements'} className={tab === 'announcements' ? 'active e-icons e-audio' : 'e-icons e-audio'} onClick={() => setActiveTab('announcements')} title="Announcements">
</button>
</div>

<div className="annc-panel-subhead">
{tab === 'notifications' ? <span>Notifications for the last 15 days</span> : <span>Announcements</span>}
<button className="annc-panel-cta" type="button" onClick={() => onMarkAllRead?.(tab)}>
{tab === 'notifications' ? (
<span>Notifications for the last 15 days</span>
) : (
<span>Announcements</span>
)}
<ButtonComponent
cssClass="annc-panel-cta"
type="button"
onClick={handleMarkAllRead}
>
Mark all read
</button>
</ButtonComponent>
</div>

<div className="annc-panel-content" role="region" aria-live="polite">
Expand All @@ -138,17 +169,8 @@ export const AnnouncementPanel: React.FC<AnnouncementPanelProps> = ({
onKeyDown={(e) => e.key === 'Enter' && openDetail(it)}
title="View details"
>
<span className={`annc-item-icon ${tab === 'announcements' ? 'bullhorn' : ''}`}>
<svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true">
<path
fill="currentColor"
d={
tab === 'announcements'
? 'M3 10v4a1 1 0 0 0 1 1h1l3.89 2.6a2 2 0 0 0 3.11-1.65V7.05A2 2 0 0 0 8.89 5.4L5 8H4a1 1 0 0 0-1 1zm18-4v12l-8-4V10l8-4z'
: 'M12 22a2 2 0 0 0 2-2h-4a2 2 0 0 0 2 2zm6-6V11a6 6 0 1 0-12 0v5l-2 2v1h16v-1l-2-2z'
}
/>
</svg>
<span className="panel-item-icon" aria-hidden="true">
<i className={it.iconClass ?? (it.type === 'announcement' ? 'e-icons e-audio' : 'e-icons e-multiple-comment')} />
</span>
<div className="annc-item-body">
<div className="annc-item-title">{it.title}</div>
Expand All @@ -164,7 +186,9 @@ export const AnnouncementPanel: React.FC<AnnouncementPanelProps> = ({
</ul>
) : (
<div className="annc-panel-empty">
{tab === 'notifications' ? 'No notification for the last 15 days.' : 'No announcements for the last 15 days.'}
{tab === 'notifications'
? 'No notification for the last 15 days.'
: 'No announcements for the last 15 days.'}
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@ export type AnnouncementDetailDialogProps = {
const dialogAnimation: AnimationSettingsModel = { effect: 'Zoom', duration: 140 };

const BullhornIcon = () => (
<svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
<path fill="currentColor" d="M3 10v4a1 1 0 0 0 1 1h1l3.89 2.6a2 2 0 0 0 3.11-1.65V7.05A2 2 0 0 0 8.89 5.4L5 8H4a1 1 0 0 0-1 1zm18-4v12l-8-4V10l8-4z" />
</svg>
<div className="e-icons e-audio"></div>
);
const BellIcon = () => (
<svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
<path fill="currentColor" d="M12 22a2 2 0 0 0 2-2h-4a2 2 0 0 0 2 2zm6-6V11a6 6 0 1 0-12 0v5l-2 2v1h16v-1l-2-2z" />
</svg>
<div className='e-icons e-multiple-comment'></div>
);
const MessageIcon = () => (
<svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
Expand Down Expand Up @@ -97,7 +93,7 @@ export const AnnouncementDetailDialog: React.FC<AnnouncementDetailDialogProps> =
const footerTemplate = () => (
<div className="annc-dlg-footer">
{item && (
<ButtonComponent cssClass="e-primary" onClick={() => onMarkRead?.(item)}>
<ButtonComponent cssClass="e-primary" onClick={onClose}>
Mark as read
</ButtonComponent>
)}
Expand Down
10 changes: 9 additions & 1 deletion Employee_Managment_App/src/components/Employees.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ const Employees = (props?: EmployeesProps) => {
};

const beforeRender = (args: TooltipEventArgs) => {

if(args.target.classList.contains('e-headercell')) {
(tooltipObj.current as any).content =args.target.innerText;
}
else {
const rowInfo: RowInfo = employeeGridIns.current?.getRowInfo(args.target.closest('td') as HTMLElement) as RowInfo;
const rowData = rowInfo?.rowData as EmployeeDetails;
(tooltipObj.current as any).content = `
Expand All @@ -140,14 +145,15 @@ const Employees = (props?: EmployeesProps) => {
</div>
</div>
</div>`;
}
};

return (
<div className="employees-content">
<TooltipComponent
id="content"
cssClass="e-tooltip-template-css"
target="td.infotooltip"
target="#employees_grid .e-headercell, #employees_grid td.infotooltip"
beforeRender={beforeRender}
ref={tooltipObj}
>
Expand All @@ -160,6 +166,7 @@ const Employees = (props?: EmployeesProps) => {
allowExcelExport={true}
//width={'100%'}
//height={'100%'}

allowGrouping={true}
groupSettings={{ enableLazyLoading: true }}
toolbar={toolbar}
Expand All @@ -177,6 +184,7 @@ const Employees = (props?: EmployeesProps) => {
field="Image"
headerText="Image"
template={imageTemplate}
clipMode='Clip'
allowFiltering={false}
allowSorting={false}
allowGrouping={false}
Expand Down
Loading