2025-07-27 10:05:37 -07:00
|
|
|
import { type ClassValue, clsx } from "clsx";
|
|
|
|
|
import { twMerge } from "tailwind-merge";
|
2025-04-07 23:47:06 -07:00
|
|
|
|
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
2025-07-27 10:05:37 -07:00
|
|
|
return twMerge(clsx(inputs));
|
2025-04-07 23:47:06 -07:00
|
|
|
}
|
2025-11-14 00:25:08 +02:00
|
|
|
|
2025-12-24 18:03:22 -08:00
|
|
|
export const formatDate = (date: Date): string => {
|
|
|
|
|
return date.toLocaleDateString("en-US", {
|
|
|
|
|
year: "numeric",
|
|
|
|
|
month: "long",
|
|
|
|
|
day: "numeric",
|
|
|
|
|
});
|
|
|
|
|
};
|
2026-02-04 18:54:59 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Copy text to clipboard with fallback for older browsers and non-secure contexts.
|
|
|
|
|
* Returns true if successful, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
export async function copyToClipboard(text: string): Promise<boolean> {
|
|
|
|
|
// Use modern Clipboard API if available and in secure context
|
|
|
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
|
|
|
try {
|
|
|
|
|
await navigator.clipboard.writeText(text);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error("Clipboard API failed:", err);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fallback for non-secure contexts or browsers without Clipboard API
|
|
|
|
|
const textArea = document.createElement("textarea");
|
|
|
|
|
textArea.value = text;
|
|
|
|
|
|
|
|
|
|
// Avoid scrolling to bottom
|
|
|
|
|
textArea.style.top = "0";
|
|
|
|
|
textArea.style.left = "0";
|
|
|
|
|
textArea.style.position = "fixed";
|
|
|
|
|
textArea.style.opacity = "0";
|
|
|
|
|
|
|
|
|
|
document.body.appendChild(textArea);
|
|
|
|
|
textArea.focus();
|
|
|
|
|
textArea.select();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const successful = document.execCommand("copy");
|
|
|
|
|
document.body.removeChild(textArea);
|
|
|
|
|
return successful;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error("Fallback copy failed:", err);
|
|
|
|
|
document.body.removeChild(textArea);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|