Skip to content

Utilities

Utility functions and helpers for Lager Guru application.

Overview

Lager Guru provides utility functions for common operations like date formatting, zone distance calculations, inventory math, parsing, and formatting.

Date Helpers

Date Formatting

Format dates for display in various formats.

Location: src/lib/utils.ts (placeholder - implement as needed)

Example:

typescript
// Format date for display
function formatDate(date: Date | string): string {
  return new Date(date).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'short',
    day: 'numeric'
  });
}

// Format datetime
function formatDateTime(date: Date | string): string {
  return new Date(date).toLocaleString('en-US', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
  });
}

// Format relative time
function formatRelativeTime(date: Date | string): string {
  const now = new Date();
  const then = new Date(date);
  const diff = now.getTime() - then.getTime();
  const minutes = Math.floor(diff / 60000);
  
  if (minutes < 1) return 'Just now';
  if (minutes < 60) return `${minutes} minutes ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours} hours ago`;
  const days = Math.floor(hours / 24);
  return `${days} days ago`;
}

Zone Distance Helpers

Calculate Zone Distance

Calculate Euclidean distance between two zones.

Location: Database function compute_zone_distance()

Usage:

typescript
import { supabase } from '@/integrations/supabase/client';

async function getZoneDistance(zoneAId: string, zoneBId: string): Promise<number | null> {
  const { data, error } = await supabase.rpc('compute_zone_distance', {
    zone_a_id: zoneAId,
    zone_b_id: zoneBId
  });
  
  if (error) throw error;
  return data;
}

Update Zone Distance

Update or create zone distance record.

Location: Database function update_zone_distance()

Usage:

typescript
async function updateZoneDistance(
  fromZoneId: string,
  toZoneId: string,
  distance: number
): Promise<void> {
  const { error } = await supabase.rpc('update_zone_distance', {
    from_zone_id: fromZoneId,
    to_zone_id: toZoneId,
    distance_value: distance
  });
  
  if (error) throw error;
}

Inventory Math

Calculate Stock Levels

Calculate various inventory metrics.

Example:

typescript
// Calculate stock percentage
function calculateStockPercentage(
  current: number,
  min: number,
  max: number
): number {
  if (max === 0) return 0;
  return Math.round((current / max) * 100);
}

// Check if low stock
function isLowStock(current: number, min: number): boolean {
  return current <= min;
}

// Calculate reorder quantity
function calculateReorderQuantity(
  current: number,
  min: number,
  max: number
): number {
  return Math.max(0, max - current);
}

Stock Movement Calculations

typescript
// Calculate total inbound
function calculateTotalInbound(movements: StockMovement[]): number {
  return movements
    .filter(m => m.type === 'inbound')
    .reduce((sum, m) => sum + m.quantity, 0);
}

// Calculate total outbound
function calculateTotalOutbound(movements: StockMovement[]): number {
  return movements
    .filter(m => m.type === 'outbound')
    .reduce((sum, m) => sum + m.quantity, 0);
}

Parsing Functions

Parse Query Parameters

Parse and validate URL query parameters.

Example:

typescript
function parseQueryParams(searchParams: URLSearchParams) {
  return {
    page: parseInt(searchParams.get('page') || '1'),
    limit: parseInt(searchParams.get('limit') || '50'),
    status: searchParams.get('status') || undefined,
    search: searchParams.get('search') || undefined
  };
}

Parse JSON Safely

Safely parse JSON with error handling.

Example:

typescript
function parseJSON<T>(json: string, defaultValue: T): T {
  try {
    return JSON.parse(json) as T;
  } catch {
    return defaultValue;
  }
}

Formatters

Format Currency

Format numbers as currency.

Example:

typescript
function formatCurrency(amount: number, currency: string = 'EUR'): string {
  return new Intl.NumberFormat('de-DE', {
    style: 'currency',
    currency: currency
  }).format(amount);
}

Format Number

Format numbers with thousand separators.

Example:

typescript
function formatNumber(num: number, decimals: number = 0): string {
  return new Intl.NumberFormat('de-DE', {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals
  }).format(num);
}

Format SKU

Format SKU codes consistently.

Example:

typescript
function formatSKU(sku: string): string {
  return sku.toUpperCase().trim().replace(/\s+/g, '-');
}

Format Phone Number

Format phone numbers for display.

Example:

typescript
function formatPhoneNumber(phone: string): string {
  // Remove all non-digits
  const digits = phone.replace(/\D/g, '');
  
  // Format as +49 XXX XXXXXXX (German format)
  if (digits.length === 11 && digits.startsWith('49')) {
    return `+${digits.slice(0, 2)} ${digits.slice(2, 5)} ${digits.slice(5)}`;
  }
  
  return phone;
}

Validation Helpers

Validate Email

Validate email address format.

Example:

typescript
function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

Validate SKU

Validate SKU format.

Example:

typescript
function isValidSKU(sku: string): boolean {
  // SKU must be alphanumeric, 3-50 characters
  const skuRegex = /^[A-Z0-9-]{3,50}$/i;
  return skuRegex.test(sku);
}

Array Helpers

Group By

Group array items by a key.

Example:

typescript
function groupBy<T>(array: T[], key: keyof T): Record<string, T[]> {
  return array.reduce((result, item) => {
    const groupKey = String(item[key]);
    if (!result[groupKey]) {
      result[groupKey] = [];
    }
    result[groupKey].push(item);
    return result;
  }, {} as Record<string, T[]>);
}

Sort By

Sort array by a key.

Example:

typescript
function sortBy<T>(array: T[], key: keyof T, direction: 'asc' | 'desc' = 'asc'): T[] {
  return [...array].sort((a, b) => {
    const aVal = a[key];
    const bVal = b[key];
    
    if (aVal < bVal) return direction === 'asc' ? -1 : 1;
    if (aVal > bVal) return direction === 'asc' ? 1 : -1;
    return 0;
  });
}

String Helpers

Truncate

Truncate string to specified length.

Example:

typescript
function truncate(str: string, length: number, suffix: string = '...'): string {
  if (str.length <= length) return str;
  return str.slice(0, length - suffix.length) + suffix;
}

Slugify

Convert string to URL-friendly slug.

Example:

typescript
function slugify(str: string): string {
  return str
    .toLowerCase()
    .trim()
    .replace(/[^\w\s-]/g, '')
    .replace(/[\s_-]+/g, '-')
    .replace(/^-+|-+$/g, '');
}

Class Name Utilities

cn(...inputs)

Merge Tailwind CSS class names.

Source: src/lib/utils.ts

Usage:

typescript
import { cn } from '@/lib/utils';

function Button({ className, variant }: ButtonProps) {
  return (
    <button
      className={cn(
        'base-button-styles',
        variant === 'primary' && 'bg-blue-500',
        className
      )}
    >
      Click me
    </button>
  );
}

Type Guards

Type Checking

Check if value is of specific type.

Example:

typescript
function isString(value: unknown): value is string {
  return typeof value === 'string';
}

function isNumber(value: unknown): value is number {
  return typeof value === 'number' && !isNaN(value);
}

function isObject(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

Error Handling

Safe Async

Wrap async functions with error handling.

Example:

typescript
async function safeAsync<T>(
  fn: () => Promise<T>,
  defaultValue: T
): Promise<T> {
  try {
    return await fn();
  } catch (error) {
    console.error('Error:', error);
    return defaultValue;
  }
}

Публикувано под търговска лицензия