0%
balqalam Logo
balqalam
FeaturesCommunityPricingDocumentation
Login
  • Introduction
  • Pitch
  • Hogwarts
  • Live Demo
  • MVP
  • Roadmap
  • Launch Sprint
  • PRD
  • Get Started
  • Localhost
  • Architecture
  • Structure
  • Pattern
  • Page
  • Layout
  • Content
  • Types
  • Config
  • Actions
  • Queries
  • Authorization
  • Validation
  • Form
  • Table
  • Detail
  • Card
  • Util
  • Hooks
  • List Params
  • Views
  • README.md
  • ISSUE.md
  • Technology Stack
  • Database
  • File
  • CDN Assets
  • Entry Points
  • Dashboard
  • Authentication
  • Credentials
  • OAuth
  • Flow Diagrams
  • Multi-Tenancy
  • Offline
  • Onboarding
  • Onboarding Videos
  • Add Values
  • Admission
  • Application
  • Attendance
  • Compliance
  • Profile
  • Exams
  • Exam Wizard
  • Timetable
  • Classrooms
  • Notifications
  • Conference
  • LMS (Lumos)
Finance
  • Finance
  • Fee Management
  • Invoice
  • Wallet
  • Salary
  • Payroll
  • Timesheet
  • Expenses
  • Budget
  • Receipt
  • Accounts
  • Banking
  • Reports
  • Dashboard
  • Permissions
  • Messages
  • Integration Flow
  • Provision
  • AI Document Processing
  • Document Intelligence
  • Internationalization
  • Translation
  • Translation Guide
  • Icons
  • Docs Factory
  • Inspiration
  • Listings
  • Teachers
  • Students
  • Catalog
  • Library
  • Contributing
  • Code of conduct
  • GitHub Workflow
  • Database Seeds
  • Database Safety
  • Test Accounts
  • Playwright
  • Prettier
  • Block Rebound
Sales & GTM
  • Marketing Brief
  • Sales
  • Go-to-market
  • Marketing
  • Admission — Feature Spotlight
  • Pilot Program
  • Leads
  • Proposal
  • Outreach Templates
  • Case Study
  • Competitors
  • Landing-page teardown
  • Competitor FAQ
  • Business model
  • Shared economy
  • Traction
Fundraising & Ecosystem
  • Get Support
  • Investor Deck
  • Data Room
  • Investors
  • Accelerators
  • Incubators
  • Grants
  • Sponsors
  • Partners
  • Competitions & Hackathons
  • Universities & Training Centers

Util

PreviousNext

Pure feature helpers — formatting, validation, sorting, calculations.

util.ts holds pure feature helpers — formatters, validators, sort/filter functions, calculations. No React, no hooks, no side effects. Server-safe and testable.

Categories

CategoryPurposeReference
Formatting (~6 files)Currency, date, time, period stringsbilling/util.ts
Validation (~4 files)Domain, email, URL format checkingdomains/util.ts
Status / health (~3 files)Map status enums to labels, variants, colorsdomains/util.ts
Navigation (~2 files)Wizard step progression, progress calculationonboarding/util.ts
Sorting / filtering (~3 files)Pure array transformationsdomains/util.ts
Calculations (~4 files)Grade calculation, accounting totalsfinance/lib/accounting/utils.ts
Storage (~2 files)Draft persistence, localStorage helpersonboarding/util.ts

Naming

NameScopeLocation
util.tsFeature-scoped (singular)src/components/<feature>/util.ts
utils.tsStandalone / library (plural)src/components/<feature>/lib/utils.ts

Rules

#Rule
1Pure functions only — no React, no hooks, no state
2Import constants from config.ts, types from types.ts
3No side effects — no DB, no API, no console.log
4JSDoc on every exported function
5Stay under ~200 lines — split into lib/ subdirectory by concern

Canonical example

import {
  DOMAIN_STATUS_LABELS,
  RESERVED_DOMAINS,
  VALIDATION_RULES,
} from "./config"
import type { DomainStatus, DomainValidationResult } from "./types"
 
/**
 * Get domain status label
 */
export function getDomainStatusLabel(status: DomainStatus): string {
  return DOMAIN_STATUS_LABELS[status]
}
 
/**
 * Get domain health indicator
 */
export function getDomainHealth(
  status: DomainStatus
): "healthy" | "warning" | "critical" {
  switch (status) {
    case "verified":
      return "healthy"
    case "approved":
    case "pending":
      return "warning"
    case "rejected":
      return "critical"
    default:
      return "warning"
  }
}
 
/**
 * Validate domain with detailed error messages
 */
export function validateDomain(domain: string): DomainValidationResult {
  const errors: string[] = []
  const warnings: string[] = []
 
  if (!domain || domain.trim() === "") {
    errors.push("Domain is required")
    return { isValid: false, errors, warnings }
  }
 
  const trimmed = domain.trim().toLowerCase()
  if (trimmed.length < VALIDATION_RULES.DOMAIN_MIN_LENGTH)
    errors.push("Too short")
  if (!VALIDATION_RULES.DOMAIN_PATTERN.test(trimmed))
    errors.push("Invalid format")
 
  return { isValid: errors.length === 0, errors, warnings }
}
 
/**
 * Normalize domain (remove protocol, www, trailing slash)
 */
export function normalizeDomain(domain: string): string {
  return domain
    .trim()
    .toLowerCase()
    .replace(/^https?:\/\//, "")
    .replace(/^www\./, "")
    .replace(/\/$/, "")
}

Server-only utilities

For helpers that import server-only modules:

import "server-only"
 
export function getSchoolSecret(schoolId: string): string {
  return process.env[`SCHOOL_${schoolId}_SECRET`] || ""
}

Anti-patterns

  • 6 different formatCurrency implementations — consolidate to src/lib/formatting.ts.
  • Sort-by-date / sort-by-name duplicated across 4+ files — generic sortByField<T> in src/lib/sorting.ts.
  • Bloated files — accounting/utils.ts (507 lines) — split by concern (formatting, calculations, validation).
  • Hooks in util.ts — move to use-*.ts.
  • useState, useEffect — never in util.

What belongs where

ContentInNot in
Pure formattingutil.tscard.tsx, form.tsx
Validation helpersutil.tsvalidation.ts (Zod schemas only)
Status label mappingutil.tsconfig.ts
Sort / filterutil.tstable.tsx, all.tsx
Navigation helpersutil.tsform.tsx
Constants / enumsconfig.tsutil.ts
React hooksuse-*.tsutil.ts
Side effects (DB, API)actions.tsutil.ts

See also

  • Pattern
  • Config
  • Types
  • Hooks
CardHooks

On This Page

CategoriesNamingRulesCanonical exampleServer-only utilitiesAnti-patternsWhat belongs whereSee also

Built by Databayt ·

Welcome to balqalam.

A great journey is about to begin.