Openstatus
www.openstatus.dev
1import type { ClassValue } from "clsx";
2import { clsx } from "clsx";
3import { addDays, format } from "date-fns";
4import { twMerge } from "tailwind-merge";
5
6export function cn(...inputs: ClassValue[]) {
7 return twMerge(clsx(inputs));
8}
9
10export function wait(ms: number) {
11 return new Promise((resolve) => setTimeout(resolve, ms));
12}
13
14export function formatDate(date: Date) {
15 return format(date, "LLL dd, y");
16}
17
18export function formatDateTime(date: Date) {
19 return format(date, "LLL dd, y HH:mm:ss");
20}
21
22export function formatTime(date: Date) {
23 return format(date, "HH:mm:ss");
24}
25
26export function formatDuration(ms: number) {
27 let v = ms;
28 if (ms < 0) v = -ms;
29 const time = {
30 day: Math.floor(v / 86400000),
31 hour: Math.floor(v / 3600000) % 24,
32 min: Math.floor(v / 60000) % 60,
33 sec: Math.floor(v / 1000) % 60,
34 ms: Math.floor(v) % 1000,
35 };
36 return Object.entries(time)
37 .filter((val) => val[1] !== 0)
38 .map(([key, val]) => `${val} ${key}${val !== 1 && key !== "ms" ? "s" : ""}`)
39 .join(", ");
40}
41
42export function notEmpty<TValue>(
43 value: TValue | null | undefined,
44): value is TValue {
45 return value !== null && value !== undefined;
46}
47
48export const slugify = (str: string) => {
49 return str
50 .toLowerCase()
51 .replace(/ /g, "-")
52 .replace(/[^\w-]+/g, "");
53};
54
55export async function copyToClipboard(value: string) {
56 await navigator.clipboard.writeText(value);
57}
58
59export function numberFormatter(value: number) {
60 const formatter = Intl.NumberFormat("en", { notation: "compact" });
61 return formatter.format(value);
62}
63
64/**
65 * Whenever you select a date, it will use the midnight timestamp of that date.
66 * We need to add a day minus one second to include the whole day.
67 */
68export function manipulateDate(
69 date?: {
70 from: Date | undefined;
71 to?: Date | undefined;
72 } | null,
73) {
74 const isToDateMidnight = String(date?.to?.getTime()).endsWith("00000");
75
76 // We might wanna use `endOfDay(new Date(date.to))` here
77 const addOneDayToDate = date?.to
78 ? addDays(new Date(date.to), 1).getTime() - 1
79 : null;
80
81 return {
82 fromDate: date?.from?.getTime() || null,
83 toDate: isToDateMidnight ? addOneDayToDate : date?.to?.getTime() || null,
84 };
85}
86
87export function toCapitalize(inputString: string) {
88 const words = inputString.split(/[\s_]+/); // Split the input string by spaces or underscores
89
90 // Capitalize the first letter of each word
91 return words
92 .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
93 .join("");
94}