import { Router } from '@angular/router'; import { ConsoleFormattedStream, INFO, createLogger as _createLogger, stdSerializers } from 'browser-bunyan'; import { jwtDecode } from 'jwt-decode'; import onChange from 'on-change'; import { User } from '../../../../bizmatch-server/src/models/db.model'; import { BusinessListingCriteria, CommercialPropertyListingCriteria, JwtToken, KeycloakUser, MailInfo, UserListingCriteria } from '../../../../bizmatch-server/src/models/main.model'; import { environment } from '../../environments/environment'; export function createEmptyBusinessListingCriteria(): BusinessListingCriteria { return { start: 0, length: 0, page: 0, state: null, city: null, types: [], prompt: '', sortBy: null, criteriaType: 'businessListings', minPrice: null, maxPrice: null, minRevenue: null, maxRevenue: null, minCashFlow: null, maxCashFlow: null, minNumberEmployees: null, maxNumberEmployees: null, establishedSince: null, establishedUntil: null, realEstateChecked: false, leasedLocation: false, franchiseResale: false, title: '', brokerName: '', searchType: 'exact', radius: null, }; } export function createEmptyCommercialPropertyListingCriteria(): CommercialPropertyListingCriteria { return { start: 0, length: 0, page: 0, state: null, city: null, types: [], prompt: '', sortBy: null, criteriaType: 'commercialPropertyListings', minPrice: null, maxPrice: null, title: '', searchType: 'exact', radius: null, }; } export function createEmptyUserListingCriteria(): UserListingCriteria { return { start: 0, length: 0, page: 0, city: null, types: [], prompt: '', sortBy: null, criteriaType: 'brokerListings', brokerName: '', companyName: '', counties: [], state: '', searchType: 'exact', radius: null, }; } export function resetBusinessListingCriteria(criteria: BusinessListingCriteria) { criteria.start = 0; criteria.length = 0; criteria.page = 0; criteria.state = null; criteria.city = null; criteria.types = []; criteria.prompt = ''; criteria.sortBy = null; criteria.criteriaType = 'businessListings'; criteria.minPrice = null; criteria.maxPrice = null; criteria.minRevenue = null; criteria.maxRevenue = null; criteria.minCashFlow = null; criteria.maxCashFlow = null; criteria.minNumberEmployees = null; criteria.maxNumberEmployees = null; criteria.establishedSince = null; criteria.establishedUntil = null; criteria.realEstateChecked = false; criteria.leasedLocation = false; criteria.franchiseResale = false; criteria.title = ''; criteria.brokerName = ''; criteria.searchType = 'exact'; criteria.radius = null; } export function resetCommercialPropertyListingCriteria(criteria: CommercialPropertyListingCriteria) { criteria.start = 0; criteria.length = 0; criteria.page = 0; criteria.state = null; criteria.city = null; criteria.types = []; criteria.prompt = ''; criteria.sortBy = null; criteria.criteriaType = 'commercialPropertyListings'; criteria.minPrice = null; criteria.maxPrice = null; criteria.title = ''; criteria.searchType = 'exact'; criteria.radius = null; } export function resetUserListingCriteria(criteria: UserListingCriteria) { criteria.start = 0; criteria.length = 0; criteria.page = 0; criteria.city = null; criteria.types = []; criteria.prompt = ''; criteria.sortBy = null; criteria.criteriaType = 'brokerListings'; criteria.brokerName = ''; criteria.companyName = ''; criteria.counties = []; criteria.state = ''; criteria.searchType = 'exact'; criteria.radius = null; } export function createMailInfo(user?: User): MailInfo { return { sender: user ? { name: `${user.firstname} ${user.lastname}`, email: user.email, phoneNumber: user.phoneNumber, state: user.location?.state, comments: null } : { name: '', email: '', phoneNumber: '', state: '', comments: '' }, email: null, url: environment.mailinfoUrl, listing: null, }; } export function createLogger(name: string, level: number = INFO, options: any = {}) { return _createLogger({ name, streams: [{ level, stream: new ConsoleFormattedStream() }], serializers: stdSerializers, src: true, ...options, }); } export function formatPhoneNumber(phone: string): string { const cleaned = ('' + phone).replace(/\D/g, ''); const match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/); if (match) { return '(' + match[1] + ') ' + match[2] + '-' + match[3]; } return phone; } export const getSessionStorageHandler = function (criteriaType, path, value, previous, applyData) { sessionStorage.setItem(`${criteriaType}_criteria`, JSON.stringify(this)); console.log('Zusätzlicher Parameter:', criteriaType); }; export const getSessionStorageHandlerWrapper = param => { return function (path, value, previous, applyData) { getSessionStorageHandler.call(this, param, path, value, previous, applyData); }; }; export function routeListingWithState(router: Router, value: string, data: any) { if (value === 'business') { router.navigate(['createBusinessListing'], { state: { data } }); } else { router.navigate(['createCommercialPropertyListing'], { state: { data } }); } } export function map2User(jwt: string | null): KeycloakUser { if (jwt) { const token = jwtDecode(jwt); return { id: token.user_id, firstName: token.given_name, lastName: token.family_name, email: token.email, }; } else { return null; } } export function getImageDimensions(imageUrl: string): Promise<{ width: number; height: number }> { return new Promise(resolve => { const img = new Image(); img.onload = () => { resolve({ width: img.width, height: img.height }); }; img.src = imageUrl; }); } export function getDialogWidth(dimensions): string { const aspectRatio = dimensions.width / dimensions.height; let dialogWidth = '50vw'; // Standardbreite // Passen Sie die Breite basierend auf dem Seitenverhältnis an if (aspectRatio < 1) { dialogWidth = '30vw'; // Hochformat } else if (aspectRatio > 1) { dialogWidth = '50vw'; // Querformat } return dialogWidth; } export function compareObjects(obj1: T, obj2: T, ignoreProperties: (keyof T)[] = []): number { let differences = 0; const keys = Object.keys(obj1) as Array; for (const key of keys) { if (ignoreProperties.includes(key)) { continue; // Überspringe diese Eigenschaft, wenn sie in der Ignore-Liste ist } const value1 = obj1[key]; const value2 = obj2[key]; if (!areValuesEqual(value1, value2)) { differences++; } } return differences; } function areValuesEqual(value1: any, value2: any): boolean { if (Array.isArray(value1) || Array.isArray(value2)) { return arraysEqual(value1, value2); } if (typeof value1 === 'string' || typeof value2 === 'string') { return isEqualString(value1, value2); } if (typeof value1 === 'number' || typeof value2 === 'number') { return isEqualNumber(value1, value2); } if (typeof value1 === 'boolean' || typeof value2 === 'boolean') { return isEqualBoolean(value1, value2); } return value1 === value2; } function isEqualString(value1: any, value2: any): boolean { const isEmptyOrNullish1 = value1 === undefined || value1 === null || value1 === ''; const isEmptyOrNullish2 = value2 === undefined || value2 === null || value2 === ''; return (isEmptyOrNullish1 && isEmptyOrNullish2) || value1 === value2; } function isEqualNumber(value1: any, value2: any): boolean { const isZeroOrNullish1 = value1 === undefined || value1 === null || value1 === 0; const isZeroOrNullish2 = value2 === undefined || value2 === null || value2 === 0; return (isZeroOrNullish1 && isZeroOrNullish2) || value1 === value2; } function isEqualBoolean(value1: any, value2: any): boolean { const isFalseOrNullish1 = value1 === undefined || value1 === null || value1 === false; const isFalseOrNullish2 = value2 === undefined || value2 === null || value2 === false; return (isFalseOrNullish1 && isFalseOrNullish2) || value1 === value2; } function arraysEqual(arr1: any[] | null | undefined, arr2: any[] | null | undefined): boolean { if (arr1 === arr2) return true; if (arr1 == null || arr2 == null) return false; if (arr1.length !== arr2.length) return false; for (let i = 0; i < arr1.length; i++) { if (!areValuesEqual(arr1[i], arr2[i])) return false; } return true; } export function assignProperties(target, source) { for (let key in source) { if (source.hasOwnProperty(key)) { target[key] = source[key]; } } return target; } export function checkAndUpdate(changed: boolean, condition: boolean, assignment: () => any): boolean { if (condition) { assignment(); } return changed || condition; } // ----------------------------- // Criteria Proxy // ----------------------------- export function getCriteriaStateObject(criteriaType: 'businessListings' | 'commercialPropertyListings' | 'brokerListings') { let initialState; if (criteriaType === 'businessListings') { initialState = createEmptyBusinessListingCriteria(); } else if (criteriaType === 'commercialPropertyListings') { initialState = createEmptyCommercialPropertyListingCriteria(); } else { initialState = createEmptyUserListingCriteria(); } const storedState = sessionStorage.getItem(`${criteriaType}`); return storedState ? JSON.parse(storedState) : initialState; } export function getCriteriaProxy(path: string, component: any): BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria { if ('businessListings' === path) { return createEnhancedProxy(getCriteriaStateObject('businessListings'), component); } else if ('commercialPropertyListings' === path) { return createEnhancedProxy(getCriteriaStateObject('commercialPropertyListings'), component); } else if ('brokerListings' === path) { return createEnhancedProxy(getCriteriaStateObject('brokerListings'), component); } else { return undefined; } } export function createEnhancedProxy(obj: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria, component: any) { const sessionStorageHandler = function (path, value, previous, applyData) { sessionStorage.setItem(`${obj.criteriaType}`, JSON.stringify(this)); }; return onChange(obj, function (path, value, previous, applyData) { // Call the original sessionStorageHandler sessionStorageHandler.call(this, path, value, previous, applyData); // Notify about the criteria change using the component's context if (component.criteriaChangeService) { component.criteriaChangeService.notifyCriteriaChange(); } }); } // export function isAdmin(email: string) { // return 'andreas.knuth@gmail.com' === email; // }