mirror of
https://github.com/hex248/sprint.git
synced 2026-02-08 02:33:01 +00:00
88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
import { type ClassValue, clsx } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
export function issueID(key: string, num: number) {
|
|
return `${key}-${num.toString().padStart(3, "0")}`;
|
|
}
|
|
|
|
export function getCsrfToken(): string | null {
|
|
return sessionStorage.getItem("csrfToken");
|
|
}
|
|
|
|
export function setCsrfToken(token: string): void {
|
|
sessionStorage.setItem("csrfToken", token);
|
|
}
|
|
|
|
export function clearAuth(): void {
|
|
sessionStorage.removeItem("csrfToken");
|
|
localStorage.removeItem("user");
|
|
localStorage.removeItem("selectedOrganisationId");
|
|
localStorage.removeItem("selectedOrganisationSlug");
|
|
localStorage.removeItem("selectedProjectId");
|
|
localStorage.removeItem("selectedProjectKey");
|
|
localStorage.removeItem("selectedIssueNumber");
|
|
}
|
|
|
|
export function capitalise(str: string) {
|
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
}
|
|
|
|
const ENV_SERVER_URL = import.meta.env.VITE_SERVER_URL?.trim();
|
|
|
|
export function getServerURL() {
|
|
let serverURL =
|
|
localStorage.getItem("serverURL") || // user-defined server URL
|
|
ENV_SERVER_URL || // environment variable
|
|
"https://tnirps.ob248.com"; // fallback
|
|
if (serverURL.endsWith("/")) {
|
|
serverURL = serverURL.slice(0, -1);
|
|
}
|
|
return serverURL;
|
|
}
|
|
|
|
export function formatTime(ms: number): string {
|
|
const totalSeconds = Math.floor(ms / 1000);
|
|
const hours = Math.floor(totalSeconds / 3600);
|
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
const seconds = totalSeconds % 60;
|
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${seconds
|
|
.toString()
|
|
.padStart(2, "0")}`;
|
|
}
|
|
|
|
export const DARK_TEXT_COLOUR = "#0a0a0a";
|
|
const THRESHOLD = 0.6;
|
|
|
|
export const isLight = (hex: string): boolean => {
|
|
const num = Number.parseInt(hex.replace("#", ""), 16);
|
|
const r = (num >> 16) & 255;
|
|
const g = (num >> 8) & 255;
|
|
const b = num & 255;
|
|
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
return luminance > THRESHOLD;
|
|
};
|
|
|
|
export const unCamelCase = (str: string): string => {
|
|
return str.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/^./, (char) => char.toUpperCase());
|
|
};
|
|
|
|
export const formatDuration = (ms: number): string => {
|
|
if (ms === 0) return "0s";
|
|
|
|
const totalSeconds = Math.floor(ms / 1000);
|
|
const hours = Math.floor(totalSeconds / 3600);
|
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
const seconds = totalSeconds % 60;
|
|
|
|
const parts: string[] = [];
|
|
if (hours > 0) parts.push(`${hours}h`);
|
|
if (minutes > 0) parts.push(`${minutes}m`);
|
|
if (seconds > 0 || (hours === 0 && minutes === 0)) parts.push(`${seconds}s`);
|
|
|
|
return parts.join(" ") || "0s";
|
|
};
|