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`;
} |