/* * File: helpers.ts * Description: General helper functions for common operations * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */ import { AlertPriority, PatientStatus } from '../types'; // ============================================================================ // ARRAY HELPERS - Functions for array manipulation and processing // ============================================================================ /** * chunk Function * * Purpose: Split an array into smaller chunks of specified size * * @param array - The array to be chunked * @param size - The size of each chunk * @returns Array of arrays, each containing up to 'size' elements * * Example: * chunk([1, 2, 3, 4, 5, 6], 2) → [[1, 2], [3, 4], [5, 6]] * * Use case: Pagination, displaying data in groups */ export const chunk = (array: T[], size: number): T[][] => { const chunks: T[][] = []; for (let i = 0; i < array.length; i += size) { chunks.push(array.slice(i, i + size)); } return chunks; }; /** * groupBy Function * * Purpose: Group array elements by a specified key function * * @param array - The array to be grouped * @param key - Function that returns the grouping key for each element * @returns Object with keys as group names and values as arrays of grouped items * * Example: * groupBy(patients, patient => patient.department) * → { 'Emergency': [patient1, patient2], 'ICU': [patient3] } * * Use case: Organizing patients by department, status, or priority */ export const groupBy = ( array: T[], key: (item: T) => K ): Record => { return array.reduce((groups, item) => { const group = key(item); if (!groups[group]) { groups[group] = []; } groups[group].push(item); return groups; }, {} as Record); }; // ============================================================================ // OBJECT HELPERS - Functions for object manipulation and transformation // ============================================================================ /** * pick Function * * Purpose: Create a new object with only specified properties from the original * * @param obj - The source object * @param keys - Array of property names to include * @returns New object containing only the specified properties * * Example: * pick({ name: 'John', age: 30, id: 1 }, ['name', 'age']) * → { name: 'John', age: 30 } * * Use case: Extracting specific patient data fields */ export const pick = , K extends keyof T>(obj: T, keys: K[]): Pick => { const result = {} as Pick; keys.forEach(key => { if (key in obj) { result[key] = obj[key]; } }); return result; }; /** * omit Function * * Purpose: Create a new object excluding specified properties from the original * * @param obj - The source object * @param keys - Array of property names to exclude * @returns New object without the specified properties * * Example: * omit({ name: 'John', age: 30, id: 1 }, ['id']) * → { name: 'John', age: 30 } * * Use case: Removing sensitive data before sending to API */ export const omit = , K extends keyof T>(obj: T, keys: K[]): Omit => { const result = { ...obj }; keys.forEach(key => { delete result[key]; }); return result; }; // ============================================================================ // STRING HELPERS - Functions for string manipulation and formatting // ============================================================================ /** * capitalize Function * * Purpose: Capitalize the first letter of a string and lowercase the rest * * @param str - The string to capitalize * @returns Capitalized string * * Example: * capitalize('john doe') → 'John doe' * * Use case: Formatting patient names, department names */ export const capitalize = (str: string): string => { return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); }; /** * truncate Function * * Purpose: Truncate a string to specified length and add ellipsis * * @param str - The string to truncate * @param length - Maximum length before truncation * @returns Truncated string with ellipsis if needed * * Example: * truncate('Very long diagnosis text', 15) → 'Very long diagn...' * * Use case: Displaying long text in limited space (diagnoses, notes) */ export const truncate = (str: string, length: number): string => { if (str.length <= length) return str; return str.slice(0, length) + '...'; }; // ============================================================================ // NUMBER HELPERS - Functions for number manipulation and validation // ============================================================================ /** * clamp Function * * Purpose: Constrain a number between minimum and maximum values * * @param value - The number to clamp * @param min - Minimum allowed value * @param max - Maximum allowed value * @returns Clamped value within the specified range * * Example: * clamp(150, 0, 100) → 100 * clamp(-10, 0, 100) → 0 * * Use case: Validating vital signs, age ranges, scores */ export const clamp = (value: number, min: number, max: number): number => { return Math.min(Math.max(value, min), max); }; /** * roundToDecimal Function * * Purpose: Round a number to specified decimal places * * @param value - The number to round * @param decimals - Number of decimal places * @returns Rounded number * * Example: * roundToDecimal(3.14159, 2) → 3.14 * * Use case: Formatting vital signs, medication dosages, scores */ export const roundToDecimal = (value: number, decimals: number): number => { return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals); }; // ============================================================================ // BOOLEAN HELPERS - Functions for boolean operations and validation // ============================================================================ /** * isTruthy Function * * Purpose: Check if a value is truthy (converts to true) * * @param value - The value to check * @returns Boolean indicating if value is truthy * * Example: * isTruthy('hello') → true * isTruthy(0) → false * * Use case: Validating form inputs, checking optional fields */ export const isTruthy = (value: any): boolean => { return Boolean(value); }; /** * isFalsy Function * * Purpose: Check if a value is falsy (converts to false) * * @param value - The value to check * @returns Boolean indicating if value is falsy * * Example: * isFalsy('') → true * isFalsy(null) → true * * Use case: Checking for empty or null values */ export const isFalsy = (value: any): boolean => { return !Boolean(value); }; // ============================================================================ // FUNCTION HELPERS - Functions for function manipulation and optimization // ============================================================================ /** * debounce Function * * Purpose: Create a debounced version of a function that delays execution * * @param func - The function to debounce * @param delay - Delay in milliseconds * @returns Debounced function * * Example: * const debouncedSearch = debounce(searchPatients, 300); * // Only executes search after 300ms of no input * * Use case: Search inputs, API calls, form validation */ export const debounce = any>( func: T, delay: number ): ((...args: Parameters) => void) => { let timeoutId: number; return (...args: Parameters) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func(...args), delay); }; }; /** * throttle Function * * Purpose: Create a throttled version of a function that limits execution frequency * * @param func - The function to throttle * @param delay - Minimum time between executions in milliseconds * @returns Throttled function * * Example: * const throttledScroll = throttle(handleScroll, 100); * // Only executes once every 100ms maximum * * Use case: Scroll events, resize events, real-time updates */ export const throttle = any>( func: T, delay: number ): ((...args: Parameters) => void) => { let lastCall = 0; return (...args: Parameters) => { const now = Date.now(); if (now - lastCall >= delay) { lastCall = now; func(...args); } }; }; // ============================================================================ // MEDICAL HELPERS - Healthcare-specific utility functions // ============================================================================ /** * getPriorityColor Function * * Purpose: Get the appropriate color for alert priority levels * * @param priority - The alert priority level * @returns Hex color code for the priority * * Color Mapping: * - CRITICAL: Red (#F44336) - Immediate attention required * - HIGH: Orange (#FF9800) - High priority attention * - MEDIUM: Blue (#2196F3) - Normal priority * - LOW: Green (#4CAF50) - Low priority * - Default: Gray (#9E9E9E) - Unknown priority * * Use case: Color-coding alerts, patient cards, status indicators */ export const getPriorityColor = (priority: AlertPriority): string => { switch (priority) { case 'CRITICAL': return '#F44336'; // Red for critical alerts case 'HIGH': return '#FF9800'; // Orange for high priority case 'MEDIUM': return '#2196F3'; // Blue for medium priority case 'LOW': return '#4CAF50'; // Green for low priority default: return '#9E9E9E'; // Gray for unknown priority } }; /** * getStatusColor Function * * Purpose: Get the appropriate color for patient status levels * * @param status - The patient status * @returns Hex color code for the status * * Color Mapping: * - CRITICAL: Red (#F44336) - Critical patient condition * - ACTIVE: Blue (#2196F3) - Currently under care * - PENDING: Orange (#FF9800) - Waiting for treatment * - DISCHARGED: Green (#4CAF50) - Successfully discharged * - TRANSFERRED: Gray (#9E9E9E) - Transferred to another facility * * Use case: Color-coding patient cards, status badges, dashboard indicators */ export const getStatusColor = (status: PatientStatus): string => { switch (status) { case 'CRITICAL': return '#F44336'; // Red for critical patients case 'ACTIVE': return '#2196F3'; // Blue for active patients case 'PENDING': return '#FF9800'; // Orange for pending patients case 'DISCHARGED': return '#4CAF50'; // Green for discharged patients case 'TRANSFERRED': return '#9E9E9E'; // Gray for transferred patients default: return '#9E9E9E'; // Gray for unknown status } }; /** * calculateAge Function * * Purpose: Calculate age from date of birth * * @param dateOfBirth - The patient's date of birth * @returns Age in years * * Logic: * - Calculates year difference * - Adjusts for month and day to get accurate age * - Handles leap years and month length variations * * Example: * calculateAge(new Date('1990-05-15')) → 33 (if current year is 2023) * * Use case: Displaying patient age, age-based calculations, demographics */ export const calculateAge = (dateOfBirth: Date): number => { const today = new Date(); let age = today.getFullYear() - dateOfBirth.getFullYear(); const monthDiff = today.getMonth() - dateOfBirth.getMonth(); // Adjust age if birthday hasn't occurred this year if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < dateOfBirth.getDate())) { age--; } return age; }; // ============================================================================ // VALIDATION HELPERS - Functions for data validation // ============================================================================ /** * isValidEmail Function * * Purpose: Validate email address format * * @param email - The email address to validate * @returns Boolean indicating if email is valid * * Validation Rules: * - Must contain @ symbol * - Must have text before and after @ * - Must have domain extension * * Use case: Login forms, user registration, contact information */ export const isValidEmail = (email: string): boolean => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); }; /** * isValidPhone Function * * Purpose: Validate phone number format * * @param phone - The phone number to validate * @returns Boolean indicating if phone number is valid * * Validation Rules: * - Minimum 10 digits * - Allows +, spaces, hyphens, parentheses * - International format supported * * Use case: Contact information, emergency contacts */ export const isValidPhone = (phone: string): boolean => { const phoneRegex = /^\+?[\d\s\-\(\)]{10,}$/; return phoneRegex.test(phone); }; /** * isValidMRN Function * * Purpose: Validate Medical Record Number format * * @param mrn - The MRN to validate * @returns Boolean indicating if MRN is valid * * Validation Rules: * - 6-12 characters long * - Alphanumeric only (A-Z, 0-9) * - No special characters or spaces * * Use case: Patient identification, medical record lookup */ export const isValidMRN = (mrn: string): boolean => { const mrnRegex = /^[A-Z0-9]{6,12}$/; return mrnRegex.test(mrn); }; // ============================================================================ // ASYNC HELPERS - Functions for asynchronous operations // ============================================================================ /** * sleep Function * * Purpose: Create a delay for specified milliseconds * * @param ms - Milliseconds to delay * @returns Promise that resolves after the delay * * Example: * await sleep(1000); // Wait for 1 second * * Use case: Rate limiting, loading states, animation delays */ export const sleep = (ms: number): Promise => { return new Promise(resolve => setTimeout(resolve, ms)); }; /** * retry Function * * Purpose: Retry an async function with exponential backoff * * @param fn - The async function to retry * @param retries - Number of retry attempts (default: 3) * @param delay - Initial delay in milliseconds (default: 1000) * @returns Promise that resolves with function result or rejects after all retries * * Retry Strategy: * - Exponential backoff (delay doubles after each failure) * - Stops after specified number of retries * - Throws error if all retries fail * * Example: * const result = await retry(fetchPatientData, 3, 1000); * * Use case: API calls, network requests, database operations */ export const retry = async ( fn: () => Promise, retries: number = 3, delay: number = 1000 ): Promise => { try { return await fn(); } catch (error) { if (retries > 0) { await sleep(delay); return retry(fn, retries - 1, delay * 2); // Exponential backoff } throw error; } }; /* * End of File: helpers.ts * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */