import Stripe from 'stripe'; import { BusinessListing, CommercialPropertyListing, Sender, SortByOptions, SortByTypes, User } from './db.model'; import { State } from './server.model'; export interface StatesResult { state: string; count: number; } export interface KeyValue { name: string; value: string; } export interface KeyValueAsSortBy { name: string; value: SortByOptions; type?: SortByTypes; selectName?: string; } export interface KeyValueRatio { label: string; value: number; } export interface KeyValueStyle { name: string; value: string; oldValue?: string; icon: string; textColorClass: string; } export type SelectOption = { value: T; label: string; }; export type ImageType = { name: 'propertyPicture' | 'companyLogo' | 'profile'; upload: string; delete: string; }; export type ListingCategory = { name: 'business' | 'commercialProperty'; }; export type ListingType = BusinessListing | CommercialPropertyListing; export type ResponseBusinessListingArray = { results: BusinessListing[]; totalCount: number; }; export type ResponseBusinessListing = { data: BusinessListing; }; export type ResponseCommercialPropertyListingArray = { results: CommercialPropertyListing[]; totalCount: number; }; export type ResponseCommercialPropertyListing = { data: CommercialPropertyListing; }; export type ResponseUsersArray = { results: User[]; totalCount: number; }; export interface ListCriteria { start: number; length: number; page: number; types: string[]; state: string; city: GeoResult; prompt: string; sortBy: SortByOptions; searchType: 'exact' | 'radius'; // radius: '5' | '20' | '50' | '100' | '200' | '300' | '400' | '500'; radius: number; criteriaType: 'businessListings' | 'commercialPropertyListings' | 'brokerListings'; } export interface BusinessListingCriteria extends ListCriteria { minPrice: number; maxPrice: number; minRevenue: number; maxRevenue: number; minCashFlow: number; maxCashFlow: number; minNumberEmployees: number; maxNumberEmployees: number; establishedMin: number; realEstateChecked: boolean; leasedLocation: boolean; franchiseResale: boolean; title: string; brokerName: string; email: string; criteriaType: 'businessListings'; } export interface CommercialPropertyListingCriteria extends ListCriteria { minPrice: number; maxPrice: number; title: string; criteriaType: 'commercialPropertyListings'; } export interface UserListingCriteria extends ListCriteria { brokerName: string; companyName: string; counties: string[]; criteriaType: 'brokerListings'; } export interface KeycloakUser { id: string; createdTimestamp?: number; username?: string; enabled?: boolean; totp?: boolean; emailVerified?: boolean; firstName: string; lastName: string; email: string; disableableCredentialTypes?: any[]; requiredActions?: any[]; notBefore?: number; access?: Access; attributes?: Attributes; } export interface JwtUser { email: string; role: string; uid: string; } interface Attributes { [key: string]: any; priceID: any; } export interface Access { manageGroupMembership: boolean; view: boolean; mapRoles: boolean; impersonate: boolean; manage: boolean; } export interface Subscription { id: string; userId: string; level: string; start: Date; modified: Date; end: Date; status: string; invoices: Array; } export interface Invoice { id: string; date: Date; price: number; } export interface JwtToken { exp: number; iat: number; auth_time: number; jti: string; iss: string; aud: string; sub: string; typ: string; azp: string; nonce: string; session_state: string; acr: string; realm_access: Realmaccess; resource_access: Resourceaccess; scope: string; sid: string; email_verified: boolean; name: string; preferred_username: string; given_name: string; family_name: string; email: string; user_id: string; price_id: string; } export interface JwtPayload { sub: string; preferred_username: string; realm_access?: { roles?: string[]; }; [key: string]: any; // für andere optionale Felder im JWT-Payload } interface Resourceaccess { account: Realmaccess; } interface Realmaccess { roles: string[]; } export interface PageEvent { first: number; rows: number; page: number; pageCount: number; } export interface AutoCompleteCompleteEvent { originalEvent: Event; query: string; } export interface MailInfo { sender: Sender; email: string; url: string; listing?: BusinessListing; } // export interface Sender { // name?: string; // email?: string; // phoneNumber?: string; // state?: string; // comments?: string; // } export interface ImageProperty { id: string; code: string; name: string; } export interface ErrorResponse { fields?: FieldError[]; general?: string[]; } export interface FieldError { fieldname: string; message: string; } export interface UploadParams { type: 'uploadPropertyPicture' | 'uploadCompanyLogo' | 'uploadProfile'; imagePath: string; serialId?: number; } export interface GeoResult { id: number; name: string; street?: string; housenumber?: string; county?: string; zipCode?: number; state: string; latitude: number; longitude: number; } interface CityResult { id: number; type: 'city'; content: GeoResult; } interface StateResult { id: number; type: 'state'; content: State; } export type CityAndStateResult = CityResult | StateResult; export interface CountyResult { id: number; name: string; state: string; state_code: string; } export interface LogMessage { severity: 'error' | 'info'; text: string; } export interface ModalResult { accepted: boolean; criteria?: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria; } export interface Checkout { priceId: string; email: string; name: string; } export type UserRole = 'admin' | 'pro' | 'guest' | null; export interface FirebaseUserInfo { uid: string; email: string | null; displayName: string | null; photoURL: string | null; phoneNumber: string | null; disabled: boolean; emailVerified: boolean; role: UserRole; creationTime?: string; lastSignInTime?: string; customClaims?: Record; } export interface UsersResponse { users: FirebaseUserInfo[]; totalCount: number; pageToken?: string; } export function isEmpty(value: any): boolean { // Check for undefined or null if (value === undefined || value === null) { return true; } // Check for empty string or string with only whitespace if (typeof value === 'string') { return value.trim().length === 0; } // Check for number and NaN if (typeof value === 'number') { return isNaN(value); } // If it's not a string or number, it's not considered empty by this function return false; } export function emailToDirName(email: string): string { if (email === undefined || email === null) { return null; } // Entferne ungültige Zeichen und ersetze sie durch Unterstriche const sanitizedEmail = email.replace(/[^a-zA-Z0-9_-]/g, '_'); // Entferne führende und nachfolgende Unterstriche const trimmedEmail = sanitizedEmail.replace(/^_+|_+$/g, ''); // Ersetze mehrfache aufeinanderfolgende Unterstriche durch einen einzelnen Unterstrich const normalizedEmail = trimmedEmail.replace(/_+/g, '_'); return normalizedEmail; } export const LISTINGS_PER_PAGE = 12; export interface ValidationMessage { field: string; message: string; } export function createDefaultUser(email: string, firstname: string, lastname: string, subscriptionPlan: 'professional' | 'broker'): User { return { id: undefined, email, firstname, lastname, phoneNumber: null, description: null, companyName: null, companyOverview: null, companyWebsite: null, location: null, offeredServices: null, areasServed: [], hasProfile: false, hasCompanyLogo: false, licensedIn: [], gender: null, customerType: 'buyer', customerSubType: null, created: new Date(), updated: new Date(), subscriptionId: null, subscriptionPlan: subscriptionPlan, }; } export function createDefaultCommercialPropertyListing(): CommercialPropertyListing { return { id: undefined, serialId: undefined, email: null, type: null, title: null, description: null, location: null, price: null, favoritesForUser: [], draft: false, imageOrder: [], imagePath: null, created: null, updated: null, listingsCategory: 'commercialProperty', }; } export function createDefaultBusinessListing(): BusinessListing { return { id: undefined, email: null, type: null, title: null, description: null, location: null, price: null, favoritesForUser: [], draft: false, realEstateIncluded: false, leasedLocation: false, franchiseResale: false, salesRevenue: null, cashFlow: null, supportAndTraining: null, employees: null, established: null, internalListingNumber: null, reasonForSale: null, brokerLicencing: null, internals: null, created: null, updated: null, listingsCategory: 'business', }; } export type StripeSubscription = Stripe.Subscription; export type StripeUser = Stripe.Customer; export type IpInfo = { ip: string; city: string; region: string; country: string; loc: string; // Coordinates in "latitude,longitude" format org: string; postal: string; timezone: string; }; export interface CombinedUser { keycloakUser?: KeycloakUser; appUser?: User; stripeUser?: StripeUser; stripeSubscription?: StripeSubscription; } export interface RealIpInfo { ip: string; countryCode?: string; }