All files / lib utils.ts

78.26% Statements 36/46
81.08% Branches 30/37
69.23% Functions 9/13
78.94% Lines 30/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92        3820x       3x       5x 4x 3x 1x       1x 1x 1x       37x 2x     37x       2x             37x                                       5x   4x 4x           7x 6x 3x 2x 2x 2x       5x 5x   3x     3x 1x       2x 7x  
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
 
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}
 
export function getStrapiURL() {
  return process.env.NEXT_PUBLIC_STRAPI_BASE_URL ?? "http://localhost:1337";
}
 
export function getStrapiMedia(url: string | null) {
  if (url == null) return null;
  if (url.startsWith("data:")) return url;
  if (url.startsWith("http") || url.startsWith("//")) return url;
  return `${getStrapiURL()}${url}`;
}
 
export function formatDate(dateString: string) {
  const date = new Date(dateString);
  const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric' };
  return date.toLocaleDateString('en-US', options);
}
 
 
export const truncate = (text: string, length: number) => {
  return text.length > length ? text.slice(0, length) + "..." : text;
};
 
export const formatNumber = (
  number: number,
  locale: string = "en-US"
): string => {
  return new Intl.NumberFormat(locale, {
    style: "decimal",
    minimumFractionDigits: 0,
    maximumFractionDigits: 2,
  }).format(number);
};
 
export const extractTextFromRichText = (content: any): string => {
  if (!content) return "";
 
  if (Array.isArray(content)) {
    return content
      .map((block) => (block.type === "paragraph" ? block.children.map((child: any) => child.text).join(" ") : ""))
      .join("\n"); // Join paragraphs with newlines
  }
 
  return String(content);
};
 
export function calculateReadingTime(text: string): number {
  const wordsPerMinute = 225;
  const wordCount = text.split(/\s+/).length;
  return Math.ceil(wordCount / wordsPerMinute);
}
 
 
export function isValidUrl(url?: string): boolean {
  if (!url) return false;
  
  const urlPattern = /^(\/[\w-./?%&=]*)$|^(https?:\/\/(localhost|\d{1,3}(\.\d{1,3}){3}|[\w.-]+)(:\d+)?(\/[\w-./?%&=]*)?)$/;  
  return urlPattern.test(url);
}
 
 
export function formatLPA(salary: string): string {
  // Handle range like "500000-800000"
  if (salary.includes("-")) {
    const [min, max] = salary.split("-").map((s) => parseFloat(s.trim()) / 100000);
    if (!isNaN(min) && !isNaN(max)) {
      const fmtMin = min < 1 ? `${parseFloat((min * 100000).toLocaleString("en-IN"))}` : `${min}L`;
      const fmtMax = max < 1 ? `${parseFloat((max * 100000).toLocaleString("en-IN"))}` : `${max}L`;
      return `${fmtMin} – ${fmtMax} per annum`;
    }
  }
 
  const num = parseFloat(salary);
  if (isNaN(num)) return salary; // fallback for "Not disclosed" etc.
 
  const lpa = num / 100000;
 
  // Below 1 lakh — show raw value in Indian format (e.g. 75,000)
  if (lpa < 1) {
    return `${num.toLocaleString("en-IN")} per annum`;
  }
 
  // Avoid trailing zeros: 1200000 → 12, not 12.0
  const formatted = Number.isInteger(lpa) ? lpa : parseFloat(lpa.toFixed(2));
  return `${formatted} LPA`;
}