Commit 9dc41150 authored by Administrator's avatar Administrator

Update 30 files via Son of Anton

parents
This diff is collapsed.
{
"name": "@the-grind/shared",
"version": "1.0.0",
"description": "Shared types, enums, and socket events for The Grind HR Platform",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"dev": "tsc --watch"
},
"dependencies": {},
"devDependencies": {
"typescript": "^5.3.3"
}
}
\ No newline at end of file
export enum ConversationType {
DIRECT = 'DIRECT',
GROUP = 'GROUP',
}
export enum MessageType {
TEXT = 'TEXT',
FILE = 'FILE',
SYSTEM = 'SYSTEM',
}
export enum NotificationType {
PASSIVE = 'PASSIVE',
IMPORTANT = 'IMPORTANT',
BLOCKING = 'BLOCKING',
}
export enum NotificationCategory {
CARD = 'CARD',
BOARD = 'BOARD',
SALARY = 'SALARY',
DEDUCTION = 'DEDUCTION',
BOUNTY = 'BOUNTY',
ADJUSTMENT = 'ADJUSTMENT',
PAYROLL = 'PAYROLL',
REPORT = 'REPORT',
EVALUATION = 'EVALUATION',
PIP = 'PIP',
MESSAGE = 'MESSAGE',
MEETING = 'MEETING',
NOTICE = 'NOTICE',
POLICY = 'POLICY',
ONBOARDING = 'ONBOARDING',
UNAVAILABILITY = 'UNAVAILABILITY',
SCHEDULE = 'SCHEDULE',
SYSTEM = 'SYSTEM',
}
\ No newline at end of file
export enum DeductionType {
MANUAL = 'MANUAL',
AUTO_LATE_REPORT = 'AUTO_LATE_REPORT',
AUTO_MISSED_REPORT = 'AUTO_MISSED_REPORT',
AUTO_PIP = 'AUTO_PIP',
PRESET = 'PRESET',
}
export enum DeductionStatus {
PENDING = 'PENDING',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
APPEALED = 'APPEALED',
REVERSED = 'REVERSED',
}
export enum AdjustmentType {
ADVANCE = 'ADVANCE',
REIMBURSEMENT = 'REIMBURSEMENT',
BONUS = 'BONUS',
CORRECTION = 'CORRECTION',
OTHER = 'OTHER',
}
export enum AdjustmentStatus {
PENDING = 'PENDING',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
}
export enum BountyStatus {
PENDING = 'PENDING',
EARNED = 'EARNED',
PAID = 'PAID',
CANCELLED = 'CANCELLED',
}
export enum PayrollStatus {
DRAFT = 'DRAFT',
CALCULATING = 'CALCULATING',
REVIEW = 'REVIEW',
APPROVED = 'APPROVED',
PAID = 'PAID',
CANCELLED = 'CANCELLED',
}
\ No newline at end of file
export * from './roles.enum';
export * from './kanban.enum';
export * from './financial.enum';
export * from './communication.enum';
export * from './reports.enum';
export * from './performance.enum';
export * from './status.enum';
\ No newline at end of file
export enum BoardVisibility {
PUBLIC = 'PUBLIC',
PRIVATE = 'PRIVATE',
TEAM = 'TEAM',
}
export enum BoardMemberRole {
OWNER = 'OWNER',
ADMIN = 'ADMIN',
MEMBER = 'MEMBER',
VIEWER = 'VIEWER',
}
export enum CardPriority {
CRITICAL = 'CRITICAL',
HIGH = 'HIGH',
MEDIUM = 'MEDIUM',
LOW = 'LOW',
NONE = 'NONE',
}
export enum RecurrencePattern {
DAILY = 'DAILY',
WEEKLY = 'WEEKLY',
BIWEEKLY = 'BIWEEKLY',
MONTHLY = 'MONTHLY',
CUSTOM = 'CUSTOM',
}
\ No newline at end of file
export enum EvaluationStatus {
DRAFT = 'DRAFT',
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
ACKNOWLEDGED = 'ACKNOWLEDGED',
}
export enum PIPStatus {
ACTIVE = 'ACTIVE',
PASSED = 'PASSED',
FAILED = 'FAILED',
EXTENDED = 'EXTENDED',
CANCELLED = 'CANCELLED',
}
export enum LearningGoalStatus {
NOT_STARTED = 'NOT_STARTED',
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
CANCELLED = 'CANCELLED',
}
\ No newline at end of file
export enum ReportStatus {
DRAFT = 'DRAFT',
SUBMITTED = 'SUBMITTED',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
AMENDMENT_REQUESTED = 'AMENDMENT_REQUESTED',
}
\ No newline at end of file
export enum Role {
SUPER_ADMIN = 'SUPER_ADMIN',
ADMIN = 'ADMIN',
TEAM_LEAD = 'TEAM_LEAD',
CONTRACTOR = 'CONTRACTOR',
}
export enum ContractorType {
FULL_TIME = 'FULL_TIME',
PART_TIME = 'PART_TIME',
PROJECT_BASED = 'PROJECT_BASED',
}
export enum UserStatus {
INVITED = 'INVITED',
ONBOARDING = 'ONBOARDING',
ACTIVE = 'ACTIVE',
ON_PIP = 'ON_PIP',
SUSPENDED = 'SUSPENDED',
OFFBOARDING = 'OFFBOARDING',
OFFBOARDED = 'OFFBOARDED',
}
export enum InviteStatus {
PENDING = 'PENDING',
ACCEPTED = 'ACCEPTED',
EXPIRED = 'EXPIRED',
REVOKED = 'REVOKED',
}
\ No newline at end of file
export enum RequestStatus {
PENDING = 'PENDING',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
CANCELLED = 'CANCELLED',
}
export enum MeetingStatus {
SCHEDULED = 'SCHEDULED',
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
CANCELLED = 'CANCELLED',
}
export enum ContractStatus {
DRAFT = 'DRAFT',
ACTIVE = 'ACTIVE',
EXPIRED = 'EXPIRED',
TERMINATED = 'TERMINATED',
}
export enum OffboardingStatus {
PENDING = 'PENDING',
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
CANCELLED = 'CANCELLED',
}
export enum WebhookStatus {
ACTIVE = 'ACTIVE',
INACTIVE = 'INACTIVE',
FAILED = 'FAILED',
}
export enum UnavailabilityType {
VACATION = 'VACATION',
SICK = 'SICK',
PERSONAL = 'PERSONAL',
EMERGENCY = 'EMERGENCY',
OTHER = 'OTHER',
}
export enum AuditAction {
CREATE = 'CREATE',
UPDATE = 'UPDATE',
DELETE = 'DELETE',
ARCHIVE = 'ARCHIVE',
RESTORE = 'RESTORE',
LOGIN = 'LOGIN',
LOGOUT = 'LOGOUT',
PASSWORD_RESET = 'PASSWORD_RESET',
PASSWORD_CHANGE = 'PASSWORD_CHANGE',
ROLE_CHANGE = 'ROLE_CHANGE',
STATUS_CHANGE = 'STATUS_CHANGE',
APPROVE = 'APPROVE',
REJECT = 'REJECT',
SUBMIT = 'SUBMIT',
MOVE = 'MOVE',
ASSIGN = 'ASSIGN',
UNASSIGN = 'UNASSIGN',
LOCK = 'LOCK',
UNLOCK = 'UNLOCK',
ACKNOWLEDGE = 'ACKNOWLEDGE',
BULK_ACTION = 'BULK_ACTION',
EXPORT = 'EXPORT',
IMPORT = 'IMPORT',
SETTINGS_CHANGE = 'SETTINGS_CHANGE',
GENERATE = 'GENERATE',
SEND = 'SEND',
}
\ No newline at end of file
import { LiveSalaryData } from '../types/salary.types';
export interface HUDSubscribePayload {
contractorId: string;
month: number;
year: number;
}
export interface HUDUpdatePayload {
contractorId: string;
salary: LiveSalaryData;
timestamp: string;
}
export interface HUDBountyEarnedPayload {
contractorId: string;
bountyId: string;
cardTitle: string;
amountPiasters: number;
newNetPiasters: number;
newHealthPercentage: number;
}
export interface HUDDeductionAppliedPayload {
contractorId: string;
deductionId: string;
reason: string;
amountPiasters: number;
type: string;
newNetPiasters: number;
newHealthPercentage: number;
}
export interface HUDAdjustmentAppliedPayload {
contractorId: string;
adjustmentId: string;
reason: string;
amountPiasters: number;
type: string;
newNetPiasters: number;
newHealthPercentage: number;
}
\ No newline at end of file
export * from './socket-events';
export * from './hud.events';
export * from './kanban.events';
export * from './notification.events';
export * from './message.events';
\ No newline at end of file
import { CardSummary, CardMovePayload } from '../types/card.types';
import { ColumnData, LabelData } from '../types/board.types';
export interface KanbanCardCreatedPayload {
boardId: string;
card: CardSummary;
}
export interface KanbanCardUpdatedPayload {
boardId: string;
cardId: string;
changes: Partial<CardSummary>;
}
export interface KanbanCardMovedPayload extends CardMovePayload {
boardId: string;
movedBy: string;
}
export interface KanbanCardDeletedPayload {
boardId: string;
cardId: string;
columnId: string;
}
export interface KanbanCardLockedPayload {
boardId: string;
cardId: string;
lockedBy: {
id: string;
name: string;
};
}
export interface KanbanCardUnlockedPayload {
boardId: string;
cardId: string;
}
export interface KanbanColumnPayload {
boardId: string;
column: ColumnData;
}
export interface KanbanLabelPayload {
boardId: string;
label: LabelData;
}
export interface KanbanTypingPayload {
boardId: string;
cardId: string;
userId: string;
userName: string;
}
export interface KanbanViewingCardPayload {
boardId: string;
cardId: string;
userId: string;
userName: string;
userAvatar: string | null;
}
\ No newline at end of file
import { MessageData, ConversationSummary } from '../types/message.types';
export interface MessageNewPayload {
conversationId: string;
message: MessageData;
}
export interface MessageUpdatedPayload {
conversationId: string;
messageId: string;
content: string;
}
export interface MessageDeletedPayload {
conversationId: string;
messageId: string;
}
export interface MessageTypingPayload {
conversationId: string;
userId: string;
userName: string;
}
export interface MessageReadPayload {
conversationId: string;
userId: string;
messageId: string;
readAt: string;
}
export interface ConversationCreatedPayload {
conversation: ConversationSummary;
}
\ No newline at end of file
import { NotificationData, NotificationCountData } from '../types/notification.types';
export interface NotificationNewPayload {
notification: NotificationData;
}
export interface NotificationBlockingPayload {
notification: NotificationData;
requiresAcknowledgment: true;
}
export interface NotificationCountUpdatePayload {
counts: NotificationCountData;
}
export interface NotificationReadPayload {
notificationId: string;
}
export interface NotificationAcknowledgedPayload {
notificationId: string;
}
\ No newline at end of file
/**
* ALL Socket.io event names for The Grind.
* Namespace convention: domain:action
* Room convention: entity:${entityId} or user:${userId}
*/
// ============================================================
// CONNECTION
// ============================================================
export const SOCKET_EVENTS = {
CONNECTION: {
CONNECT: 'connect',
DISCONNECT: 'disconnect',
ERROR: 'connect_error',
AUTHENTICATE: 'auth:authenticate',
AUTHENTICATED: 'auth:authenticated',
UNAUTHORIZED: 'auth:unauthorized',
},
// ============================================================
// PRESENCE
// ============================================================
PRESENCE: {
USER_ONLINE: 'presence:user_online',
USER_OFFLINE: 'presence:user_offline',
USERS_STATUS: 'presence:users_status',
REQUEST_STATUS: 'presence:request_status',
},
// ============================================================
// HUD (Salary Health Bar)
// ============================================================
HUD: {
SUBSCRIBE: 'hud:subscribe',
UNSUBSCRIBE: 'hud:unsubscribe',
UPDATE: 'hud:update',
BOUNTY_EARNED: 'hud:bounty_earned',
DEDUCTION_APPLIED: 'hud:deduction_applied',
ADJUSTMENT_APPLIED: 'hud:adjustment_applied',
SALARY_CHANGED: 'hud:salary_changed',
},
// ============================================================
// KANBAN
// ============================================================
KANBAN: {
JOIN_BOARD: 'kanban:join_board',
LEAVE_BOARD: 'kanban:leave_board',
CARD_CREATED: 'kanban:card_created',
CARD_UPDATED: 'kanban:card_updated',
CARD_MOVED: 'kanban:card_moved',
CARD_DELETED: 'kanban:card_deleted',
CARD_ARCHIVED: 'kanban:card_archived',
CARD_ASSIGNED: 'kanban:card_assigned',
CARD_UNASSIGNED: 'kanban:card_unassigned',
CARD_LOCKED: 'kanban:card_locked',
CARD_UNLOCKED: 'kanban:card_unlocked',
COLUMN_CREATED: 'kanban:column_created',
COLUMN_UPDATED: 'kanban:column_updated',
COLUMN_DELETED: 'kanban:column_deleted',
COLUMN_REORDERED: 'kanban:column_reordered',
LABEL_CREATED: 'kanban:label_created',
LABEL_UPDATED: 'kanban:label_updated',
LABEL_DELETED: 'kanban:label_deleted',
COMMENT_ADDED: 'kanban:comment_added',
COMMENT_UPDATED: 'kanban:comment_updated',
COMMENT_DELETED: 'kanban:comment_deleted',
CHECKLIST_UPDATED: 'kanban:checklist_updated',
MEMBER_JOINED: 'kanban:member_joined',
MEMBER_LEFT: 'kanban:member_left',
BOARD_UPDATED: 'kanban:board_updated',
TYPING: 'kanban:typing',
VIEWING_CARD: 'kanban:viewing_card',
},
// ============================================================
// NOTIFICATIONS
// ============================================================
NOTIFICATION: {
NEW: 'notification:new',
READ: 'notification:read',
READ_ALL: 'notification:read_all',
ACKNOWLEDGED: 'notification:acknowledged',
COUNT_UPDATE: 'notification:count_update',
BLOCKING: 'notification:blocking',
},
// ============================================================
// MESSAGES
// ============================================================
MESSAGE: {
JOIN_CONVERSATION: 'message:join_conversation',
LEAVE_CONVERSATION: 'message:leave_conversation',
NEW: 'message:new',
UPDATED: 'message:updated',
DELETED: 'message:deleted',
TYPING: 'message:typing',
STOP_TYPING: 'message:stop_typing',
READ: 'message:read',
PINNED: 'message:pinned',
UNPINNED: 'message:unpinned',
CONVERSATION_CREATED: 'message:conversation_created',
PARTICIPANT_ADDED: 'message:participant_added',
PARTICIPANT_REMOVED: 'message:participant_removed',
},
// ============================================================
// ACTIVITY FEED
// ============================================================
ACTIVITY: {
NEW_ITEM: 'activity:new_item',
SUBSCRIBE: 'activity:subscribe',
UNSUBSCRIBE: 'activity:unsubscribe',
},
// ============================================================
// REPORTS
// ============================================================
REPORT: {
SUBMITTED: 'report:submitted',
REVIEWED: 'report:reviewed',
AMENDMENT_REQUESTED: 'report:amendment_requested',
REMINDER: 'report:reminder',
},
// ============================================================
// MEETINGS
// ============================================================
MEETING: {
SCHEDULED: 'meeting:scheduled',
UPDATED: 'meeting:updated',
CANCELLED: 'meeting:cancelled',
STARTING_SOON: 'meeting:starting_soon',
RESPONSE: 'meeting:response',
},
} as const;
// Room name helpers
export const ROOMS = {
user: (userId: string) => `user:${userId}` as const,
hud: (userId: string) => `hud:${userId}` as const,
board: (boardId: string) => `board:${boardId}` as const,
card: (cardId: string) => `card:${cardId}` as const,
conversation: (conversationId: string) => `conversation:${conversationId}` as const,
activity: (scope: 'org' | 'team' | string) => `activity:${scope}` as const,
} as const;
\ No newline at end of file
export * from './enums';
export * from './types';
export * from './events';
\ No newline at end of file
export interface ApiResponse<T = unknown> {
success: boolean;
data: T;
message?: string;
meta?: ApiMeta;
}
export interface ApiMeta {
page?: number;
limit?: number;
total?: number;
totalPages?: number;
}
export interface PaginatedResponse<T> {
success: boolean;
data: T[];
meta: Required<Pick<ApiMeta, 'page' | 'limit' | 'total' | 'totalPages'>>;
}
export interface PaginationQuery {
page?: number;
limit?: number;
sortBy?: string;
sortOrder?: 'asc' | 'desc';
search?: string;
}
export interface BulkActionResult {
success: number;
failed: number;
errors: Array<{ id: string; error: string }>;
}
\ No newline at end of file
import { Role } from '../enums';
export interface AuthTokenPayload {
sub: string; // userId
email: string;
role: Role;
sessionId: string;
iat?: number;
exp?: number;
}
export interface AuthResponse {
accessToken: string;
refreshToken: string;
expiresIn: number;
user: AuthUser;
}
export interface AuthUser {
id: string;
email: string;
username: string;
firstName: string;
lastName: string;
displayName: string | null;
avatar: string | null;
role: Role;
}
export interface LoginRequest {
email: string;
password: string;
}
export interface RefreshTokenRequest {
refreshToken: string;
}
\ No newline at end of file
import { BoardVisibility, BoardMemberRole } from '../enums';
export interface BoardSummary {
id: string;
name: string;
description: string | null;
visibility: BoardVisibility;
prefix: string | null;
color: string | null;
icon: string | null;
isArchived: boolean;
memberCount: number;
cardCount: number;
createdAt: string;
}
export interface BoardDetail extends BoardSummary {
columns: ColumnData[];
labels: LabelData[];
members: BoardMemberData[];
}
export interface ColumnData {
id: string;
name: string;
position: number;
color: string | null;
wipLimit: number | null;
isDone: boolean;
cardCount: number;
}
export interface LabelData {
id: string;
name: string;
color: string;
}
export interface BoardMemberData {
id: string;
userId: string;
role: BoardMemberRole;
user: {
id: string;
firstName: string;
lastName: string;
displayName: string | null;
avatar: string | null;
};
joinedAt: string;
}
\ No newline at end of file
import { CardPriority } from '../enums';
import { UserSummary } from './user.types';
import { LabelData } from './board.types';
export interface CardSummary {
id: string;
title: string;
boardId: string;
columnId: string;
position: number;
priority: CardPriority;
dueDate: string | null;
bountyPiasters: number;
coverImage: string | null;
isLocked: boolean;
assigneeCount: number;
commentCount: number;
checklistProgress: { completed: number; total: number } | null;
labels: LabelData[];
assignees: Array<Pick<UserSummary, 'id' | 'firstName' | 'lastName' | 'avatar'>>;
createdAt: string;
}
export interface CardDetail extends CardSummary {
description: string | null;
startDate: string | null;
estimatedHours: number | null;
actualHours: number | null;
lockedById: string | null;
parentCardId: string | null;
createdBy: Pick<UserSummary, 'id' | 'firstName' | 'lastName' | 'avatar'>;
watchers: Array<Pick<UserSummary, 'id' | 'firstName' | 'lastName' | 'avatar'>>;
checklists: ChecklistData[];
attachments: AttachmentData[];
subtasks: CardSummary[];
completedAt: string | null;
updatedAt: string;
}
export interface ChecklistData {
id: string;
title: string;
position: number;
items: ChecklistItemData[];
}
export interface ChecklistItemData {
id: string;
title: string;
isCompleted: boolean;
completedAt: string | null;
assigneeId: string | null;
position: number;
dueDate: string | null;
}
export interface AttachmentData {
id: string;
fileId: string;
originalName: string;
mimeType: string;
sizeBytes: number;
url: string;
createdAt: string;
}
export interface CardMovePayload {
cardId: string;
fromColumnId: string;
toColumnId: string;
position: number;
}
export interface CardFilterParams {
boardId?: string;
columnId?: string;
assigneeId?: string;
priority?: CardPriority[];
labelIds?: string[];
hasBounty?: boolean;
isOverdue?: boolean;
search?: string;
dueDateFrom?: string;
dueDateTo?: string;
}
\ No newline at end of file
import { EvaluationStatus, PIPStatus } from '../enums';
export interface EvaluationSummary {
id: string;
contractorId: string;
contractorName: string;
evaluatorName: string;
period: string;
status: EvaluationStatus;
overallScore: number | null;
createdAt: string;
}
export interface EvaluationDetail extends EvaluationSummary {
overallComments: string | null;
autoMetrics: AutoMetrics | null;
scores: EvaluationScoreData[];
acknowledgedAt: string | null;
}
export interface EvaluationScoreData {
id: string;
criteriaName: string;
criteriaWeight: number;
maxScore: number;
score: number;
comments: string | null;
}
export interface AutoMetrics {
reportSubmissionRate: number;
lateReportRate: number;
cardsCompleted: number;
averageCardCompletionDays: number;
totalBountiesEarned: number;
totalDeductions: number;
attendanceRate: number;
}
export interface PIPSummary {
id: string;
contractorId: string;
contractorName: string;
managerName: string;
status: PIPStatus;
startDate: string;
endDate: string;
goalProgress: { completed: number; total: number };
}
export interface PIPDetail extends PIPSummary {
reason: string;
goals: PIPGoalData[];
checkIns: PIPCheckInData[];
outcome: string | null;
}
export interface PIPGoalData {
id: string;
title: string;
description: string | null;
targetDate: string | null;
isCompleted: boolean;
completedAt: string | null;
order: number;
}
export interface PIPCheckInData {
id: string;
date: string;
notes: string | null;
progress: string | null;
meetingId: string | null;
}
\ No newline at end of file
export * from './api.types';
export * from './auth.types';
export * from './user.types';
export * from './board.types';
export * from './card.types';
export * from './salary.types';
export * from './notification.types';
export * from './message.types';
export * from './report.types';
export * from './evaluation.types';
export * from './pagination.types';
\ No newline at end of file
import { ConversationType, MessageType } from '../enums';
export interface ConversationSummary {
id: string;
type: ConversationType;
name: string | null;
avatar: string | null;
lastMessage: MessagePreview | null;
unreadCount: number;
participantCount: number;
participants: Array<{
id: string;
firstName: string;
lastName: string;
avatar: string | null;
isOnline: boolean;
}>;
lastMessageAt: string | null;
}
export interface MessagePreview {
id: string;
content: string | null;
type: MessageType;
senderName: string;
createdAt: string;
}
export interface MessageData {
id: string;
conversationId: string;
senderId: string;
senderName: string;
senderAvatar: string | null;
type: MessageType;
content: string | null;
fileUrl: string | null;
fileName: string | null;
replyToId: string | null;
replyToPreview: MessagePreview | null;
isEdited: boolean;
isPinned: boolean;
createdAt: string;
}
export interface SendMessagePayload {
conversationId: string;
content?: string;
type?: MessageType;
fileId?: string;
replyToId?: string;
}
\ No newline at end of file
import { NotificationType, NotificationCategory } from '../enums';
export interface NotificationData {
id: string;
type: NotificationType;
category: NotificationCategory;
title: string;
message: string;
actionUrl: string | null;
metadata: Record<string, unknown> | null;
isRead: boolean;
readAt: string | null;
acknowledgedAt: string | null;
createdAt: string;
}
export interface CreateNotificationPayload {
userId: string;
type: NotificationType;
category: NotificationCategory;
title: string;
message: string;
actionUrl?: string;
metadata?: Record<string, unknown>;
}
export interface NotificationCountData {
total: number;
unread: number;
blocking: number;
}
\ No newline at end of file
export interface PaginationParams {
page: number;
limit: number;
sortBy?: string;
sortOrder?: 'asc' | 'desc';
}
export interface PaginatedResult<T> {
data: T[];
meta: {
page: number;
limit: number;
total: number;
totalPages: number;
};
}
export interface DateRangeFilter {
from?: string;
to?: string;
}
\ No newline at end of file
import { ReportStatus } from '../enums';
export interface DailyReportSummary {
id: string;
contractorId: string;
contractorName: string;
date: string;
status: ReportStatus;
totalHours: number;
entryCount: number;
isLate: boolean;
submittedAt: string | null;
}
export interface DailyReportDetail extends DailyReportSummary {
summary: string | null;
entries: ReportEntryData[];
reviewedBy: string | null;
reviewedAt: string | null;
reviewNotes: string | null;
amendments: ReportAmendmentData[];
}
export interface ReportEntryData {
id: string;
description: string;
hoursSpent: number;
cardId: string | null;
cardTitle: string | null;
}
export interface ReportAmendmentData {
id: string;
content: string;
requestedAt: string;
resolvedAt: string | null;
}
\ No newline at end of file
export interface LiveSalaryData {
contractorId: string;
month: number;
year: number;
baseSalaryPiasters: number;
totalBountiesPiasters: number;
totalAdjustmentsPiasters: number;
totalDeductionsPiasters: number;
netSalaryPiasters: number;
healthPercentage: number; // net / base * 100
dailyRate: number;
breakdown: SalaryBreakdown;
}
export interface SalaryBreakdown {
bounties: Array<{
id: string;
cardTitle: string;
amountPiasters: number;
earnedAt: string;
}>;
deductions: Array<{
id: string;
reason: string;
amountPiasters: number;
type: string;
createdAt: string;
}>;
adjustments: Array<{
id: string;
reason: string;
amountPiasters: number;
type: string;
createdAt: string;
}>;
}
export interface HUDDisplayData {
baseSalary: string; // formatted EGP
netSalary: string;
healthPercentage: number;
healthColor: string; // green, yellow, orange, red
bountiesEarned: number;
deductionsApplied: number;
adjustmentsApplied: number;
lastUpdated: string;
}
export interface PayrollSummary {
id: string;
month: number;
year: number;
status: string;
totalGrossPiasters: number;
totalNetPiasters: number;
contractorCount: number;
createdAt: string;
}
export interface PayrollItemDetail {
id: string;
contractorId: string;
contractorName: string;
baseSalaryPiasters: number;
totalBountiesPiasters: number;
totalAdjustmentsPiasters: number;
totalDeductionsPiasters: number;
netSalaryPiasters: number;
}
\ No newline at end of file
import { Role, ContractorType, UserStatus } from '../enums';
export interface UserSummary {
id: string;
email: string;
username: string;
firstName: string;
lastName: string;
displayName: string | null;
avatar: string | null;
role: Role;
status: UserStatus;
isOnline: boolean;
}
export interface UserProfile extends UserSummary {
contractorType: ContractorType | null;
department: string | null;
title: string | null;
phone: string | null;
timezone: string;
bio: string | null;
dateOfBirth: string | null;
startDate: string | null;
lastLoginAt: string | null;
createdAt: string;
}
export interface ContractorDirectoryEntry {
id: string;
firstName: string;
lastName: string;
displayName: string | null;
avatar: string | null;
role: Role;
contractorType: ContractorType | null;
department: string | null;
title: string | null;
status: UserStatus;
isOnline: boolean;
}
export interface UserFilterParams {
role?: Role;
status?: UserStatus;
contractorType?: ContractorType;
department?: string;
search?: string;
}
\ No newline at end of file
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment