76cb29d31e
- Updated the TenderDetails component to validate country codes using a new utility function, isValidAlpha2CountryCode. - Modified the useGetFlagQuery hook to accept an options parameter for conditional fetching based on the validity of the country code. - Improved the rendering logic for the country flag to ensure it only displays when valid flag data is available.
113 lines
2.7 KiB
TypeScript
113 lines
2.7 KiB
TypeScript
import { ILabelValue } from "@/types/shared";
|
|
import * as moment from "moment";
|
|
import { z } from "zod";
|
|
export const unixToDate = ({
|
|
hasTime = false,
|
|
unix,
|
|
}: {
|
|
unix: number;
|
|
hasTime?: boolean;
|
|
}) => {
|
|
return moment.unix(unix).format(`YYYY/MM/DD - ${hasTime ? "HH:MM" : ""}`);
|
|
};
|
|
export const msToDate = (ms: number) => {
|
|
return moment.default(ms).format("YYYY/MM/DD");
|
|
};
|
|
|
|
export const isoStringToDate = ({
|
|
hasTime = false,
|
|
isoString,
|
|
}: {
|
|
isoString: string;
|
|
hasTime: boolean;
|
|
}): string => {
|
|
return moment
|
|
.default(isoString)
|
|
.format(`YYYY/MM/DD ${hasTime ? "HH:MM" : ""}`);
|
|
};
|
|
|
|
export const getStatusColor = <T>(status: T) => {
|
|
switch (status) {
|
|
case "active":
|
|
return "bg-green text-white";
|
|
case "expired":
|
|
return "bg-orange-light text-white";
|
|
case "cancelled":
|
|
return "bg-error-dark text-white";
|
|
case "awarded":
|
|
return "bg-blue-light-3";
|
|
case "draft":
|
|
return "bg-gray-3";
|
|
}
|
|
};
|
|
export const formatPhoneNumber = (input?: string) => {
|
|
if (!input) return "";
|
|
|
|
let cleaned = input.replace(/[^\d+]/g, "");
|
|
|
|
const hasPlus = cleaned.startsWith("+");
|
|
if (hasPlus) {
|
|
cleaned = cleaned.slice(1);
|
|
}
|
|
|
|
const groups = [];
|
|
let i = 0;
|
|
while (i < cleaned.length) {
|
|
const size = i === 0 ? 3 : 4;
|
|
groups.push(cleaned.slice(i, i + size));
|
|
i += size;
|
|
}
|
|
|
|
return (hasPlus ? "+" : "") + groups.join(" ");
|
|
};
|
|
export const capitalize = (text: string) => {
|
|
return text
|
|
.split(" ")
|
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
.join(" ")
|
|
.trim();
|
|
};
|
|
export const getEnumAsArray = <T extends object>(target: T): ILabelValue[] => {
|
|
return Object.entries(target).map(([key, value]) => ({
|
|
label: capitalize(key.split("_").join(" ")),
|
|
value,
|
|
}));
|
|
};
|
|
export const truncateString = (
|
|
str: string,
|
|
startLength: number = 10,
|
|
endLength: number = 10,
|
|
): string => {
|
|
if (str.length <= startLength + endLength) {
|
|
return str;
|
|
}
|
|
return str.slice(0, startLength) + "..." + str.slice(-endLength);
|
|
};
|
|
|
|
export function parseWithSchema<T>(
|
|
schema: z.ZodSchema<T>,
|
|
data: unknown,
|
|
errorContext: string,
|
|
): T {
|
|
const parsedData = schema.safeParse(data);
|
|
|
|
if (parsedData.success) {
|
|
return parsedData.data;
|
|
} else {
|
|
console.error(`ERROR caught in ${errorContext}`);
|
|
throw new Error(`ERROR caught in ${errorContext}`);
|
|
}
|
|
}
|
|
|
|
export const deleteEmptyKeys = (obj: Record<string, any>) => {
|
|
const newObj = { ...obj };
|
|
for (const key in newObj) {
|
|
if (Object.prototype.hasOwnProperty.call(newObj, key)) {
|
|
if (!newObj[key]) {
|
|
delete newObj[key];
|
|
}
|
|
}
|
|
}
|
|
return newObj;
|
|
};
|
|
export const isValidAlpha2CountryCode = (code: string) => /^[A-Za-z]{2}$/.test(code); |