Added partner app

This commit is contained in:
2026-09-28 16:13:42 +02:00
parent 242a4c6fbb
commit 7d510d9fbc
36 changed files with 5920 additions and 0 deletions
@@ -0,0 +1,98 @@
import Hashids from 'hashids';
import { useQuery } from '@tanstack/react-query';
export const HASHER_SETTINGS = {
minHashLength: 11,
salt: 'TGlnaHQgQ2hhcm1zLCBNaWRyYW5kQm9va3MgbWFrZSBsb3RzIG9mIG1vbmV5IGFuZCBhcmUgYSBzdWNjZXNzZnVsIHZpcmFsIHN0b3J5IGluIFNvdXRoIEFmcmljYQ==',
};
let hasher = new Hashids(HASHER_SETTINGS.salt, HASHER_SETTINGS.minHashLength);
export function updateHasherSettings(salt?: string, minLength?: number | string): void {
let updated = false;
if (salt && salt.trim() !== '') {
HASHER_SETTINGS.salt = salt.trim();
updated = true;
}
if (minLength !== undefined && minLength !== null && minLength !== '') {
const parsed = Number(minLength);
if (!isNaN(parsed) && parsed > 0) {
HASHER_SETTINGS.minHashLength = parsed;
updated = true;
}
}
if (updated) {
hasher = new Hashids(HASHER_SETTINGS.salt, HASHER_SETTINGS.minHashLength);
}
}
export function encodeHashIdSync(id: number | string | null | undefined): string {
if (id === undefined || id === null || id === '') return '';
if (typeof id === 'number') {
if (isNaN(id) || !isFinite(id) || id < 0) return '';
return hasher.encode(id);
}
const str = String(id).trim();
if (!str) return '';
try {
const decoded = hasher.decode(str);
if (Array.isArray(decoded) && decoded.length > 0) return str;
} catch {}
if (/^\d+$/.test(str)) {
const num = parseInt(str, 10);
if (!isNaN(num) && num >= 0) return hasher.encode(num);
}
return str;
}
export function decodeHashIdSync(hashId: string | number | null | undefined): number | string {
if (hashId === undefined || hashId === null || hashId === '') return '';
if (typeof hashId === 'number') return hashId;
const str = String(hashId).trim();
if (/^-?\d+$/.test(str)) {
const parsed = parseInt(str, 10);
return isNaN(parsed) ? str : parsed;
}
try {
const decoded = hasher.decode(str);
if (Array.isArray(decoded) && decoded.length > 0) return Number(decoded[0]);
} catch {}
return str;
}
export function decodeToNumberSync(hashId: number | string | null | undefined): number {
if (!hashId) return 0;
if (typeof hashId === 'number') return isNaN(hashId) ? 0 : Math.trunc(hashId);
const str = String(hashId).trim();
if (/^-?\d+$/.test(str)) {
const parsed = parseInt(str, 10);
return isNaN(parsed) ? 0 : parsed;
}
try {
const decoded = hasher.decode(str);
if (Array.isArray(decoded) && decoded.length > 0) return Number(decoded[0]);
} catch {}
const fallback = Number(str);
return isNaN(fallback) ? 0 : Math.trunc(fallback);
}
export const toolsService = {
encodeIdSync: encodeHashIdSync,
decodeIdSync: decodeHashIdSync,
decodeToNumberSync,
async encodeId(id: number | string | null | undefined) { return encodeHashIdSync(id); },
async decodeId(hashId: string | null | undefined) { return decodeHashIdSync(hashId); },
async resolveProjectId(id: number | string) { return encodeHashIdSync(id); },
async resolveOrganisationId(id: number | string) { return encodeHashIdSync(id); },
async resolveActivityId(id: number | string) { return encodeHashIdSync(id); },
async resolveMilestoneId(id: number | string) { return encodeHashIdSync(id); },
};
export function useHashId(id?: number | string | null, context = 'general') {
return useQuery({
queryKey: ['hashId', context, id !== undefined && id !== null ? String(id) : ''],
queryFn: () => Promise.resolve(encodeHashIdSync(id)),
enabled: id !== undefined && id !== null && id !== '',
staleTime: Infinity,
});
}