({\n title: '',\n message: '',\n cancelButtonText: '',\n confirmButtonText: '',\n onNo: () => {\n //initialization. empty by design\n },\n onYes: () => {\n //initialization. empty by design\n },\n });\n\n useEffect(() => {\n const mapPropsToState = (properties: ConfirmModalProperties) => ({\n title: properties.title || upperFirst(t('confirm')),\n message: properties.message || t('areYouSureYouWantToProceed?'),\n cancelButtonText:\n properties.cancelButtonText || upperFirst(t('cancelAction')),\n confirmButtonText: properties.confirmButtonText || 'OK',\n onYes: properties.onYes,\n onNo:\n properties.onNo ||\n (() => {\n //initialization. empty by design\n }),\n });\n\n confirm = (props) => {\n setState(mapPropsToState(props));\n setOpen(true);\n };\n }, [setState, setOpen, t]);\n\n return (\n \n \n
\n );\n};\n\nexport default ConfirmModal;\n","import { Theme } from '@mui/material/styles';\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\nimport { FontWeightProperty } from '../../types/types';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n hidden: { display: 'none' },\n disabledInput: {\n '& > .MuiInputBase-formControl': {\n backgroundColor: 'transparent !important',\n fontSize: '14px',\n },\n '& input, & .MuiSelect-select, & textarea': {\n color: theme.palette.text.primary,\n border: 'none !important',\n padding: '2px 0 !important',\n },\n '& > label': {\n display: 'none',\n },\n '& .MuiInputBase-root': {\n border: 'none !important',\n padding: '0 !important',\n },\n '& .MuiFilledInput-underline.Mui-disabled:before': {\n border: 'none',\n borderBottomStyle: 'none',\n },\n },\n select: {\n fontSize: '14px',\n '& .MuiFilledInput-input': { padding: '18.5px' },\n '& > div': { borderRadius: '14px !important' },\n },\n inputRoot: {\n position: 'relative',\n '& > .MuiFormLabel-root': {\n color: theme.palette.text.primary,\n borderRadius: '14px',\n '& > span': {\n color: theme.palette.secondary.main,\n borderRadius: '14px',\n },\n '&.Mui-focused': {\n color: theme.palette.secondary.main,\n borderRadius: '14px',\n '& > span': {\n color: theme.palette.secondary.main,\n borderRadius: '14px',\n },\n },\n },\n '& > div.MuiInputBase-root.MuiInputBase-multiline': {\n backgroundColor: 'white',\n border: `1px solid ${theme.palette.border.main}`,\n borderRadius: '14px',\n padding: 0,\n fontWeight: theme.typography.fontWeightRegular as FontWeightProperty,\n '&:hover, &.Mui-focused': {\n border: `1px solid ${theme.palette.secondary.main}`,\n },\n '&.Mui-error': {\n border: '1px solid #f44336',\n '&:hover, &.Mui-focused': {\n border: `1px solid ${theme.palette.secondary.main}`,\n },\n },\n },\n '& > p#note-helper-text': {\n position: 'absolute',\n top: '24px',\n right: 0,\n },\n '& > p#note-helper-text.Mui-focused > span > span#note-length': {\n color: theme.palette.secondary.main,\n },\n '& > .MuiInputBase-root': {\n backgroundColor: 'white',\n fontSize: '14px',\n borderRadius: '14px',\n '& > input, & > .MuiSelect-root, & > div#card, & > div#iban': {\n border: `1px solid ${theme.palette.border.main}`,\n borderRadius: '14px',\n fontWeight: theme.typography.fontWeightRegular as FontWeightProperty,\n '&:hover': {\n border: `1px solid ${theme.palette.secondary.main}`,\n },\n },\n '& > div#card, & > div#iban': {\n backgroundColor: 'white !important',\n },\n '&.Mui-focused': {\n backgroundColor: 'white',\n '& > input, & > .MuiSelect-root, & > div#card, & > div#iban': {\n border: `1px solid ${theme.palette.secondary.main}`,\n borderRadius: '14px',\n },\n '& > .MuiSelect-root:focus': {\n backgroundColor: 'white',\n },\n },\n '&.Mui-error > input, &.Mui-error > .MuiSelect-root': {\n border: '1px solid #f44336',\n borderRadius: '14px',\n },\n '&:before': {\n border: 'none',\n borderRadius: '14px',\n },\n '&:hover': {\n backgroundColor: 'white',\n '&:before': {\n border: 'none',\n },\n },\n '&:after': {\n border: 'none',\n borderRadius: '14px',\n },\n },\n },\n inputRootWithIcon: {\n '& > .MuiInputBase-root': {\n backgroundColor: 'white',\n fontWeight: theme.typography.fontWeightRegular as FontWeightProperty,\n border: `1px solid ${theme.palette.border.main}`,\n borderRadius: '4px',\n '&:hover': {\n border: `1px solid ${theme.palette.secondary.main}`,\n },\n '&.Mui-focused': {\n border: `1px solid ${theme.palette.secondary.main}`,\n },\n '& > input, & > .MuiSelect-root, & > div#card, & > div#iban': {\n border: 0,\n '&:hover': {\n border: 0,\n },\n },\n '&.Mui-error': {\n border: '1px solid #f44336',\n '&:hover, &.Mui-focused': {\n border: `1px solid ${theme.palette.secondary.main}`,\n },\n },\n '&:before': {\n border: 'none',\n },\n '&:after': {\n border: 'none',\n },\n },\n },\n multiSelect: {\n '--rmsc-main': `${theme.palette.secondary.main} !important`,\n '--rmsc-hover': `${theme.palette.grey[200]} !important`,\n '--rmsc-selected': `${theme.palette.border.main} !important`,\n '--rmsc-border': `${theme.palette.border.main} !important`,\n '--rmsc-h': '56px !important',\n },\n helperText: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n marginTop: '5px',\n '& > span': {\n margin: '2px 0px 0px 5px',\n },\n },\n textFieldRoot: {\n '& .MuiFormLabel-root': {\n fontSize: '15px',\n },\n '& .MuiInputLabel-shrink': {\n fontSize: '18px',\n },\n '& .MuiOutlinedInput-root': {\n fontSize: '14px',\n '& fieldset span': {\n fontSize: '14px',\n },\n '&.Mui-focused fieldset': {\n borderWidth: '2px',\n borderColor: '#5e6f77',\n },\n '&.Mui-error fieldset': {\n borderWidth: '2px',\n borderColor: `${theme.palette.red.main} !important`,\n fontSize: '14px',\n },\n borderRadius: '10px',\n },\n '& > label': {\n color: 'grey !important',\n '&.Mui-focused.Mui-error': {\n color: `${theme.palette.red.main} !important`,\n },\n },\n '& .MuiFormHelperText-root': {\n height: '20px',\n '&.Mui-error': {\n color: `${theme.palette.red.main} !important`,\n },\n },\n '& .MuiOutlinedInput-input': {\n borderRadius: '14px',\n fontSize: '14px',\n background: 'white',\n },\n '& .MuiInputBase-multiline': {\n background: 'white',\n },\n '& .Mui-disabled': {\n background: 'none',\n },\n },\n })\n);\n\nexport default useStyles;\n","import axios from 'axios';\nimport { appConfiguration } from '../../configuration';\nimport {\n authScopes,\n getCurrentAccount,\n acquireTokenSilentOrRefreshToken,\n} from '../auth';\nimport { PostEmailReviewerDtoIn } from './dtos/post-email-reviewer/post-email-reviewer-dto-in';\nimport { PostMailContactDtoIn } from './dtos/post-mail-contact/post-mail-contact-dto-in';\nclass MailService {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl;\n }\n\n async sendContactEmail(message: PostMailContactDtoIn): Promise {\n return axios.post(`${this.baseUrl}/mail/contact`, message);\n }\n\n async sendEmailToReviewer(\n emailReviewerDtoIn: PostEmailReviewerDtoIn\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return axios.post(\n `${this.baseUrl}/mail/contact-reviewer`,\n emailReviewerDtoIn,\n {\n headers: {\n authorization: `Bearer ${authResult.idToken}`,\n },\n }\n );\n }\n}\n\nexport const mailService = new MailService(\n appConfiguration()?.coreApiUrl ?? ''\n);\n","import { useState, useEffect } from 'react';\n\nfunction getWindowDimensions() {\n const { innerWidth: width, innerHeight: height } = window;\n return {\n width,\n height,\n };\n}\n\nexport default function useWindowDimensions() {\n const [windowDimensions, setWindowDimensions] = useState(\n getWindowDimensions()\n );\n\n useEffect(() => {\n function handleResize() {\n setWindowDimensions(getWindowDimensions());\n }\n\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n return windowDimensions;\n}\n","import React, { useEffect, useRef } from 'react';\nimport { appConfiguration } from '../configuration';\nimport { WidgetInstance } from 'friendly-challenge';\n\ntype Props = {\n onFinish: (solution: string) => void;\n onFail: (error: any) => void;\n};\n\nconst FriendlyCaptcha: React.FC = ({ onFinish, onFail }) => {\n const container = useRef();\n const widget = useRef();\n\n useEffect(() => {\n if (!widget.current && container.current) {\n widget.current = new WidgetInstance(container.current, {\n startMode: 'none',\n doneCallback: onFinish,\n errorCallback: onFail,\n });\n }\n }, [container, onFail, onFinish]);\n\n return (\n \n );\n};\n\nexport default FriendlyCaptcha;\n","import {\n Box,\n Checkbox,\n FormControlLabel,\n Grid,\n Typography,\n} from '@mui/material';\nimport { clsx } from 'clsx';\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Link } from 'react-router-dom';\nimport {\n MAX_CONTACT_FORM_MESSAGE_LENGTH,\n MIN_CONTACT_FORM_MESSAGE_LENGTH,\n} from '../../constants/constants';\nimport useWindowDimensions from '../../hooks/window-dimensions';\nimport { PostMailContactDtoIn } from '../../services/mail-service/dtos/post-mail-contact/post-mail-contact-dto-in';\nimport { mailService } from '../../services/mail-service/mail-service';\nimport { setBasicAlert } from '../../store/actions/notificationsActions';\nimport { userSelector } from '../../store/selectors';\nimport {\n CheckboxStyleProps,\n useSharedCheckboxStyles,\n} from '../../styles/checkbox.styles';\nimport { useSharedStyles } from '../../styles/Shared.styles';\nimport { emailRegex, phoneRegex } from '../../util/basic-validations';\nimport FriendlyCaptcha from '../../util/friendlyCaptcha';\nimport MPButton2 from '../button/MPButton2';\nimport MPTextField from '../input/MPTextField';\nimport LoadingIndicator from '../loading/Loading';\nimport useStyles from './ContactForm.styles';\nimport { closeContact } from './ContactFormOverlay';\n\ninterface ContactFormProps {\n largeScreenColumns: number;\n titleKey?: string;\n centerTitle?: boolean;\n successMessageKey: string;\n customEmailReceiver?: string; // this indicates that the email does not go to marketplace's contact team\n overlay?: boolean;\n disabled?: boolean;\n}\n\nconst ContactForm: React.FC = ({\n largeScreenColumns,\n titleKey,\n centerTitle,\n successMessageKey,\n customEmailReceiver,\n overlay,\n disabled,\n}) => {\n const classes = useStyles();\n const sharedClasses = useSharedStyles();\n const { t } = useTranslation();\n const dispatch = useDispatch();\n const checkboxStyleProps: CheckboxStyleProps = { isGreen: true };\n const sharedCheckboxClasses = useSharedCheckboxStyles(checkboxStyleProps);\n const user = useSelector(userSelector);\n const [isButtonDisabled, setButtonDisabled] = useState(true);\n const [messageLength, setMessageLength] = useState(0);\n const [captchaSolution, setCaptchaSolution] = useState('');\n const [isLoading, setLoading] = useState(false);\n const [formSubmitted, setFormSubmitted] = useState(false);\n const [lastEmail, setLastEmail] = useState(user?.email || '');\n const [lastPhoneNumber, setLastPhoneNumber] = useState('');\n const [contactChannels, setContactChannels] = useState({\n emailChannel: true,\n phoneChannel: true,\n });\n const [overlaySmall, setOverlaySmall] = useState(false);\n const { height } = useWindowDimensions();\n\n type ContactFields = {\n fullName: string;\n email: string;\n phoneNumber: string;\n topic: string;\n message: string;\n privacyPolicy: boolean;\n allowContact: boolean;\n };\n\n const CONTACT_FIELDS_DEFAULTS: ContactFields = {\n fullName: user?.fullName || '',\n email: user?.email || '',\n phoneNumber: '',\n topic: '',\n message: '',\n privacyPolicy: false,\n allowContact: false,\n };\n\n interface ContactChannels {\n emailChannel: boolean;\n phoneChannel: boolean;\n }\n\n interface ContactChannelButton {\n labelKey: string;\n onSelected: () => void;\n isActive: () => boolean;\n }\n\n const { register, handleSubmit, errors, getValues, setValue } =\n useForm({\n mode: 'all',\n defaultValues: {\n ...CONTACT_FIELDS_DEFAULTS,\n },\n });\n\n const contactChannelButtons: ContactChannelButton[] = [\n {\n labelKey: 'byEmailOrPhone',\n onSelected: () => {\n setContactChannels({ emailChannel: true, phoneChannel: true });\n },\n isActive: () =>\n contactChannels.emailChannel && contactChannels.phoneChannel,\n },\n {\n labelKey: 'onlyByEmail',\n onSelected: () => {\n setContactChannels({ emailChannel: true, phoneChannel: false });\n },\n isActive: () =>\n contactChannels.emailChannel && !contactChannels.phoneChannel,\n },\n {\n labelKey: 'onlyByPhone',\n onSelected: () => {\n setContactChannels({ emailChannel: false, phoneChannel: true });\n },\n isActive: () =>\n !contactChannels.emailChannel && contactChannels.phoneChannel,\n },\n ];\n\n const onSubmit = handleSubmit((data) => {\n setLoading(true);\n\n const contactFormData: PostMailContactDtoIn = {\n userName: data.fullName,\n userEmail: contactChannels.emailChannel ? data.email : undefined,\n userPhoneNumber: contactChannels.phoneChannel\n ? data.phoneNumber\n : undefined,\n topic: data.topic || ' ',\n message: data.message,\n captchaKey: captchaSolution,\n customEmailReceiver,\n };\n\n mailService\n .sendContactEmail(contactFormData)\n .then(() => {\n setFormSubmitted(true);\n setLoading(false);\n })\n .catch((err) => {\n setLoading(false);\n const error = err as any;\n const emailSendingError: string = error?.response?.data?.message;\n dispatch(\n setBasicAlert({\n messageKey: emailSendingError,\n severity: 'error',\n })\n );\n });\n });\n\n const verifyButtonAvailability = useCallback(() => {\n const {\n fullName,\n email,\n phoneNumber,\n message,\n allowContact,\n privacyPolicy,\n } = getValues();\n\n const anyEmptyFields =\n !fullName ||\n (contactChannels.emailChannel && !email) ||\n (contactChannels.phoneChannel && !phoneNumber) ||\n !message ||\n !allowContact ||\n (!customEmailReceiver && !privacyPolicy);\n\n setButtonDisabled(\n errors.allowContact !== undefined ||\n errors.email !== undefined ||\n errors.phoneNumber !== undefined ||\n errors.fullName !== undefined ||\n errors.message !== undefined ||\n (!customEmailReceiver && errors.privacyPolicy !== undefined) ||\n anyEmptyFields ||\n !captchaSolution ||\n isLoading\n );\n }, [\n captchaSolution,\n errors.allowContact,\n errors.email,\n errors.phoneNumber,\n errors.fullName,\n errors.message,\n errors.privacyPolicy,\n isLoading,\n contactChannels,\n customEmailReceiver,\n getValues,\n ]);\n\n useEffect(() => {\n setOverlaySmall((overlay && height <= 786) || false);\n }, [height, overlay]);\n\n useEffect(() => {\n lastEmail !== '' &&\n setValue('email', lastEmail, {\n shouldValidate: true,\n });\n lastPhoneNumber !== '' &&\n setValue('phoneNumber', lastPhoneNumber, {\n shouldValidate: true,\n });\n\n // adding lastEmail or lastPhoneNumber will create infinite loop\n /* eslint-disable react-hooks/exhaustive-deps*/\n }, [contactChannels]);\n\n useEffect(() => {\n verifyButtonAvailability();\n }, [captchaSolution, verifyButtonAvailability]);\n\n if (formSubmitted) {\n return (\n \n \n \n {t('contactSuccessGreeting')}\n \n \n {t(successMessageKey)}\n \n \n \n );\n }\n\n return (\n \n {titleKey && (\n \n {t(titleKey)}\n \n )}\n \n \n );\n};\n\nexport default ContactForm;\n","export enum CollectionMethod {\n CHARGE_AUTOMATICALLY = 'charge_automatically',\n SEND_INVOICE = 'send_invoice',\n}\n\nexport enum PaymentMethodId {\n INVOICE_PAYMENT_ID = 'invoice_payment_id',\n}\n\nexport enum SubscriptionStatus {\n ACTIVE = 'active',\n CANCELED = 'canceled',\n TERMINATED = 'terminated',\n PENDING = 'pendingDate',\n NEW = 'new',\n REJECTED = 'rejected',\n FINALIZED = 'finalized',\n TECHNICAL_CONFIGURATION = 'technical configuration',\n}\n\nexport enum SubscriptionApiKey {\n PRIMARY = 'primaryKey',\n SECONDARY = 'secondaryKey',\n}\n\nexport enum MemberStatus {\n PENDING = 'pending',\n ACTIVE = 'active',\n UPDATING = 'updating',\n NOT_FOUND = 'not_found',\n}\n\nexport enum AvailabilityStatus {\n ACTIVE = 'ACTIVE',\n DISABLED = 'DISABLED',\n}\n\nexport enum PlanSourceType {\n PER_REQUEST = 'per_request',\n RESPONSE_HEADER = 'response_header',\n PROVIDER_PUSH = 'provider_push',\n}\n\nexport enum AuthMode {\n NONE = 'none',\n BASIC = 'basic',\n OAUTH = 'oauth',\n CUSTOM_HEADER = 'custom_header',\n CUSTOM_FLOW = 'custom_flow',\n}\n\nexport enum ProductStatus {\n DRAFT = 'draft',\n IN_REVIEW = 'in_review',\n IN_TECHNICAL_CONFIGURATION = 'in_technical_configuration',\n APPROVED = 'approved',\n PENDING = 'pending',\n ACTIVE = 'active',\n FAILED = 'failed',\n INACTIVE = 'inactive',\n}\n\nexport enum SignalRChannel {\n SUBSCRIPTIONS = 'subscriptions',\n PARTNERS = 'partners',\n PRODUCTS = 'products',\n NOTIFICATIONS = 'notifications',\n}\n\nexport enum SignalRMessageType {\n EMPTY = 'empty',\n SUBSCRIPTION_ACTIVATED = 'subscription-activated',\n SUBSCRIPTION_CANCELED = 'subscription-canceled',\n SUBSCRIPTION_TERMINATED = 'subscription-terminated',\n MEMBER_ROLE_CHANGED = 'member-role-changed',\n PRODUCT_CREATED = 'product-created',\n PRODUCT_CREATION_FAILED = 'product-creation-failed',\n PARTNER_UPDATED = 'partner-updated',\n}\n\nexport enum SpecFormat {\n OPENAPI = 'openapi+json-link',\n WSDL = 'wsdl-link',\n}\n\nexport enum NotificationSeverityType {\n INFORMATIVE = 'INFORMATIVE',\n IMPORTANT = 'IMPORTANT',\n CRITICAL = 'CRITICAL',\n}\n\nexport enum NotificationReadStatus {\n READ = 'READ',\n UNREAD = 'UNREAD',\n}\n\nexport enum NotificationStatus {\n AVAILABLE = 'AVAILABLE',\n ARCHIVED = 'ARCHIVED',\n}\n\nexport enum NotificationType {\n SERVICE_SUBSCRIPTION_CREATED = 'SERVICE_SUBSCRIPTION_CREATED',\n}\n\nexport enum SubscriptionNotificationPhase {\n USER_READY_TO_USE = 'USER_READY_TO_USE',\n PARTNER_READY_TO_USE = 'PARTNER_READY_TO_USE',\n PARTNER_NEW_SUBSCRIBER = 'PARTNER_NEW_SUBSCRIBER',\n}\n\nexport enum PeriodTermsTimeUnit {\n YEAR = 'YEAR',\n MONTH = 'MONTH',\n}\n\nexport enum ApiType {\n REST = 'rest',\n SOAP = 'soap',\n SOAP_TO_REST = 'soap_to_rest',\n CUSTOM = 'custom',\n NONE = 'none',\n}\n\nexport enum ProductAction {\n SEND_TO_REVIEW = 'send-to-review',\n REVIEW_ACCEPTED = 'review-accepted',\n REVIEW_DECLINED = 'review-declined',\n TECHNICAL_CONFIGURATION_FINISHED = 'technical-configuration-finished',\n PUBLISH = 'publish',\n}\n\nexport enum SubscriptionAction {\n CONFIRM = 'confirm-subscription',\n REJECT = 'reject-subscription',\n}\n\nexport enum SelfServicePricePlanType {\n ONE_TIME = 'ONE_TIME',\n RECURRING = 'RECURRING',\n CUSTOM = 'CUSTOM',\n}\n\nexport enum Category {\n ALL_PRODUCTS = 'ALL_PRODUCTS',\n PRODUCTS = 'PRODUCTS',\n SALES_MANAGEMENT = 'SALES_MANAGEMENT',\n PROPOSAL = 'PROPOSAL',\n CONTRACT = 'CONTRACT',\n CLAIMS_BENEFITS = 'CLAIMS_BENEFITS',\n PAYMENT = 'PAYMENT',\n CAPITAL_INVESTMENT = 'CAPITAL_INVESTMENT',\n REINSURANCE = 'REINSURANCE',\n SALES_AND_CUSTOMER = 'SALES_AND_CUSTOMER',\n INFORMATION_AND_REPORTING = 'INFORMATION_AND_REPORTING',\n STRATEGY = 'STRATEGY',\n PLANNING_AND_CONTROLLING = 'PLANNING_AND_CONTROLLING',\n RISK_MANAGEMENT = 'RISK_MANAGEMENT',\n PROCESSES_AND_ORGANIZATION = 'PROCESSES_AND_ORGANIZATION',\n HUMAN_RESOURCES = 'HUMAN_RESOURCES',\n PROJECTS = 'PROJECTS',\n MARKETING_AND_COMMUNICATION = 'MARKETING_AND_COMMUNICATION',\n IT = 'IT',\n INPUT_OUTPUT = 'INPUT_OUTPUT',\n REWE = 'REWE',\n LEGAL_AND_COMPLIANCE = 'LEGAL_AND_COMPLIANCE',\n PROCUREMENT = 'PROCUREMENT',\n INTERNAL_SERVICES = 'INTERNAL_SERVICES',\n HEALTH = 'HEALTH',\n}\n\nexport enum Industry {\n CROSS_INDUSTRY = 'CROSS_INDUSTRY',\n AUTOMOTIVE = 'AUTOMOTIVE',\n BANKING = 'BANKING',\n CUSTOMER_PRODUCTS = 'CUSTOMER_PRODUCTS',\n FOOD = 'FOOD',\n HEALTHCARE = 'HEALTHCARE',\n INSURANCE = 'INSURANCE',\n LIFE_SCIENCE_AND_CHEMICALS = 'LIFE_SCIENCE_AND_CHEMICALS',\n MANUFACTURING = 'MANUFACTURING',\n PUBLIC_SECTOR = 'PUBLIC_SECTOR',\n REINSURANCE = 'REINSURANCE',\n TELECOMMUNICATION = 'TELECOMMUNICATION',\n TRAVEL_AND_LOGISTICS = 'TRAVEL_AND_LOGISTICS',\n UTILITIES = 'UTILITIES',\n OTHER = 'OTHER',\n}\n\nexport enum BusinessProductType {\n PRODUCT_ADDON = 'PRODUCT_ADDON',\n SERVICE_WORKSHOP = 'SERVICE_WORKSHOP',\n}\n\nexport enum FulfillmentMethod {\n EMAIL = 'Email',\n API = 'API',\n}\n\nexport enum PlanName {\n PAY_AS_YOU_GO = 'PAY_AS_YOU_GO',\n BASIC = 'BASIC',\n BUSINESS = 'BUSINESS',\n ENTERPRISE = 'ENTERPRISE',\n FREE_TIER = 'FREE_TIER',\n}\n\nexport enum Interval {\n DAY = 'day',\n WEEK = 'week',\n MONTH = 'month',\n YEAR = 'year',\n}\n\nexport enum PriceModel {\n FIXED = 'fixed',\n TRANSACTIONAL = 'transactional',\n ONE_OFF = 'one-off',\n GRADUATED_TRANSACTIONAL = 'graduated-transactional',\n}\n\nexport enum SecurityActionType {\n MEMBER_ROLE_CHANGE,\n PAYMENT_METHODS_MODIFICATION,\n API_KEYS_RENEWAL,\n}\n\nexport enum ProductType {\n LISTING = 'listing',\n SOFTWARE_AS_A_SERVICE = 'software_as_a_service',\n}\n\nexport enum BillingSystem {\n STRIPE = 'Stripe',\n NONE = 'None',\n MSG = 'Msg',\n}\n\nexport enum PaymentMethodType {\n CARD = 'card',\n SEPA = 'sepa',\n WIRE_TRANSFER = 'wire-transfer',\n}\n\nexport enum BlockType {\n VIDEO = 'video',\n TEXT_AND_IMAGE = 'text-and-image',\n IMAGE_AND_TEXT = 'image-and-text',\n TEXT = 'text',\n}\n\nexport enum TextBlockContentAlignment {\n LEFT = 'left',\n RIGHT = 'right',\n CENTER = 'center',\n}\n\nexport enum ProductsFilterType {\n SOLUTION = 'solution',\n INDUSTRY = 'industry',\n PROVIDER = 'provider',\n}\n\n/* eslint-disable import/no-unused-modules*/\nexport enum AspectRatio {\n ONE_BY_ONE = 1,\n FOUR_BY_THREE = 4 / 3,\n FIVE_BY_THREE = 5 / 3,\n}\n\nexport enum CustomStyleDimension {\n MIN_HEIGHT_AND_WEIGHT = 'min',\n MAX_HEIGHT_AND_WEIGHT = 'max',\n DEFAULT_HEIGHT_AND_WEIGHT = 'default',\n}\n\nexport enum PurchaseType {\n ONE_TIME = 'ONE_TIME',\n RECURRING = 'RECURRING',\n}","const routes = {\n home: '/',\n productCatalog: '/catalog',\n checkout: {\n base: '/checkout/:id/:planId',\n success: '/checkout-success/:subscriptionId',\n },\n dashboard: {\n base: '/dashboard',\n paymentMethods: '/payment-methods',\n subscriptions: '/subscriptions',\n products: '/products',\n billing: '/billing',\n partnerDetails: '/partner-details',\n partnerMembers: '/partner-members',\n partnerApplications: '/partner-applications',\n subscriptionUsage: '/subscription-usage',\n subscriptionCost: '/subscription-cost',\n securityLogs: '/security-logs',\n newProduct: '/product-configuration',\n productConfiguration: '/product-configuration/:productId?',\n },\n service: '/service/:id/:tab',\n profile: '/profile',\n ourVision: '/our-vision',\n favoriteProducts: '/favoriteProducts',\n imprint: '/imprint',\n dataPrivacy: '/data-privacy',\n termsOfUse: '/terms-of-use',\n notFound: '*',\n invitation: '/invitation/:id',\n};\n\nexport default routes;\n","import axios from 'axios';\nimport axiosRetry, { isNetworkOrIdempotentRequestError } from 'axios-retry';\n\naxios.defaults.timeout = 120_000;\n\naxiosRetry(axios, {\n retries: 0,\n shouldResetTimeout: true,\n // Retry delay: 1=2s 2=4s 3=8s\n retryDelay: (retryCount) => {\n return Math.pow(2, retryCount) * 1000;\n },\n // Retry on\n // Http verbs: GET, HEAD, OPTIONS, PUT, DELETE\n // Http statuses: [500-599] or canceled requests (ex. timeouts)\n retryCondition: (error) => {\n return (\n isNetworkOrIdempotentRequestError(error) || error.code === 'ECONNABORTED'\n );\n },\n});\n\nexport default axios;\n","import { ActionCreator, Dispatch } from 'redux';\nimport { ThunkAction } from 'redux-thunk';\nimport { AppState } from '..';\nimport { NotificationDataType } from '../../models/userNotification';\nimport { notificationService } from '../../services/user-notifications/user-notifications-service';\n\nexport enum UserNotificationsActionTypes {\n LOAD_BATCH = 'Load all user notifications',\n LOAD_BATCH_OF_NOTIFICATIONS_SUCCESS = 'Load batch of notifications success',\n LOAD_FIRST_BATCH_OF_NOTIFICATIONS_SUCCESS = 'Load first batch of notifications success',\n NOTIFICATION_RECEIVED = 'Notification received',\n GET_UNREAD_COUNT = 'Get unread count',\n GET_UNREAD_NOTIFICATIONS_COUNT_SUCCESS = 'Get unread notifications count success',\n UPDATE_HAS_MORE_PAGES = 'Update has more pages',\n READ_ALL_NOTIFICATIONS = 'Read all notifications',\n READ_ALL_NOTIFICATIONS_SUCCESS = 'Read all notifications success',\n UPDATE_CURRENT_PAGE_NUMBER = 'Update current page number',\n REMOVE_NOTIFICATION_BY_ID = 'Removes a notification from the list by its ID',\n}\n\ninterface LoadBatchOfUserNotificationsAction {\n type: typeof UserNotificationsActionTypes.LOAD_BATCH;\n}\n\nexport const loadBatchOfUserNotifications: ActionCreator<\n ThunkAction, AppState, null, LoadBatchOfUserNotificationsAction>\n> = (partnerId: string, page: number) => {\n return async (dispatch: Dispatch) => {\n try {\n const notifications =\n await notificationService.getBatchOfUserNotifications(partnerId, page);\n if (page === 0) {\n dispatch(loadFirstBatchOfNotificationsSuccess(notifications));\n } else {\n dispatch(loadBatchOfNotificationsSuccess(notifications));\n }\n } catch (err) {\n console.error(err);\n }\n };\n};\n\ninterface LoadFirstBatchOfNotificationsSuccessAction {\n type: typeof UserNotificationsActionTypes.LOAD_FIRST_BATCH_OF_NOTIFICATIONS_SUCCESS;\n data: NotificationDataType[];\n}\n\nconst loadFirstBatchOfNotificationsSuccess = (\n data: NotificationDataType[]\n): LoadFirstBatchOfNotificationsSuccessAction => ({\n type: UserNotificationsActionTypes.LOAD_FIRST_BATCH_OF_NOTIFICATIONS_SUCCESS,\n data,\n});\n\ninterface LoadBatchOfNotificationsSuccessAction {\n type: typeof UserNotificationsActionTypes.LOAD_BATCH_OF_NOTIFICATIONS_SUCCESS;\n data: NotificationDataType[];\n}\n\nconst loadBatchOfNotificationsSuccess = (\n data: NotificationDataType[]\n): LoadBatchOfNotificationsSuccessAction => ({\n type: UserNotificationsActionTypes.LOAD_BATCH_OF_NOTIFICATIONS_SUCCESS,\n data,\n});\n\ninterface LoadUnreadNotificationsCountAction {\n type: typeof UserNotificationsActionTypes.GET_UNREAD_COUNT;\n}\n\nexport const loadUnreadNotificationsCount: ActionCreator<\n ThunkAction, AppState, null, LoadUnreadNotificationsCountAction>\n> = (partnerId: string) => {\n return async (dispatch: Dispatch) => {\n try {\n const unreadNotificatonsCount =\n await notificationService.getUnreadNotificationsCount(partnerId);\n dispatch(loadUnreadNotificationsCountSuccess(unreadNotificatonsCount));\n } catch (err) {\n console.error(err);\n }\n };\n};\n\ninterface LoadUnreadNotificationsCountSuccessAction {\n type: typeof UserNotificationsActionTypes.GET_UNREAD_NOTIFICATIONS_COUNT_SUCCESS;\n data: number;\n}\n\nconst loadUnreadNotificationsCountSuccess = (\n data: number\n): LoadUnreadNotificationsCountSuccessAction => ({\n type: UserNotificationsActionTypes.GET_UNREAD_NOTIFICATIONS_COUNT_SUCCESS,\n data,\n});\n\ninterface ReadAllUserNotificationsAction {\n type: typeof UserNotificationsActionTypes.READ_ALL_NOTIFICATIONS;\n}\n\nexport const markAllNotificationsAsRead: ActionCreator<\n ThunkAction, AppState, null, ReadAllUserNotificationsAction>\n> = (partnerId: string, latestNotificationTimestamp: number) => {\n return async (dispatch: Dispatch, getState) => {\n if (Object.keys(getState().userNotifications.notifications).length >= 1) {\n try {\n await notificationService.markAllNotificationsAsRead(\n partnerId,\n latestNotificationTimestamp\n );\n dispatch(readAllNotificationsSuccess());\n } catch (err) {\n console.error(err);\n }\n }\n };\n};\n\nexport const archiveUserNotification: ActionCreator<\n ThunkAction, AppState, null, ReadAllUserNotificationsAction>\n> = (partnerId: string, notificationId: string) => {\n return async (dispatch: Dispatch) => {\n try {\n await notificationService.archiveUserNotification(\n partnerId,\n notificationId\n );\n dispatch(archieveNotificationById(notificationId));\n } catch (err) {\n console.error(err);\n }\n };\n};\n\ninterface ReadAllNotificationsSuccessAction {\n type: typeof UserNotificationsActionTypes.READ_ALL_NOTIFICATIONS_SUCCESS;\n}\n\nconst readAllNotificationsSuccess = (): ReadAllNotificationsSuccessAction => ({\n type: UserNotificationsActionTypes.READ_ALL_NOTIFICATIONS_SUCCESS,\n});\n\ninterface ArchiveNotificationByIdAction {\n type: typeof UserNotificationsActionTypes.REMOVE_NOTIFICATION_BY_ID;\n data: string;\n}\n\nconst archieveNotificationById = (\n notificationId: string\n): ArchiveNotificationByIdAction => ({\n type: UserNotificationsActionTypes.REMOVE_NOTIFICATION_BY_ID,\n data: notificationId,\n});\n\ninterface UpdateHasMorePagesAction {\n type: typeof UserNotificationsActionTypes.UPDATE_HAS_MORE_PAGES;\n data: boolean;\n}\n\nexport const updateHasMorePages = (\n data: boolean\n): UpdateHasMorePagesAction => ({\n type: UserNotificationsActionTypes.UPDATE_HAS_MORE_PAGES,\n data,\n});\n\ninterface UpdateCurrentPageNumberAction {\n type: typeof UserNotificationsActionTypes.UPDATE_CURRENT_PAGE_NUMBER;\n data: number;\n}\n\nexport const updateCurrentPageNumber = (\n data: number\n): UpdateCurrentPageNumberAction => ({\n type: UserNotificationsActionTypes.UPDATE_CURRENT_PAGE_NUMBER,\n data,\n});\n\ninterface NotificationReceivedAction {\n type: typeof UserNotificationsActionTypes.NOTIFICATION_RECEIVED;\n data: NotificationDataType;\n}\n\nexport const notificationReceivedSuccess = (\n data: NotificationDataType\n): NotificationReceivedAction => ({\n type: UserNotificationsActionTypes.NOTIFICATION_RECEIVED,\n data,\n});\n\nexport type UserNotificationsActions =\n | LoadBatchOfUserNotificationsAction\n | LoadBatchOfNotificationsSuccessAction\n | NotificationReceivedAction\n | LoadUnreadNotificationsCountAction\n | LoadUnreadNotificationsCountSuccessAction\n | UpdateHasMorePagesAction\n | UpdateCurrentPageNumberAction\n | ReadAllUserNotificationsAction\n | ReadAllNotificationsSuccessAction\n | LoadFirstBatchOfNotificationsSuccessAction\n | ArchiveNotificationByIdAction;\n","import { createContext } from 'react';\n\ntype GlobalCookieContent = {\n statisticCookie: boolean;\n setStatisticCookieContext: (c: boolean) => void;\n};\nexport const CookieContext = createContext({\n statisticCookie: false,\n setStatisticCookieContext: () => {\n //this is the initialization of the Context. intentional empty function\n },\n});\n","import { Theme } from '@mui/material/styles';\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\nimport { Distances } from '../../AppTheme';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n modalWrapper: {\n display: 'block',\n borderTop: `1px solid ${theme.palette.border.main}`,\n paddingBottom: '20px',\n paddingTop: '20px',\n background: 'white',\n bottom: 0,\n position: 'fixed',\n float: 'right',\n [theme.breakpoints.down('md')]: {\n width: '100%',\n },\n },\n modalSizeNoSidebar: {\n width: '100% !important',\n },\n modalSizeWithSidebar: {\n width: 'calc(100% - 260px)',\n },\n contentWrapper: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-between',\n },\n textWrapper: {\n justifySelf: 'start',\n display: 'flex',\n flexDirection: 'column',\n paddingRight: Distances.FIELD,\n },\n smallTextWrapper: {\n flexDirection: 'row',\n minHeight: '48px',\n },\n checkboxWrapper: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'start',\n },\n formLabel: {\n '&.MuiFormControlLabel-root': {\n marginLeft: 0,\n paddingLeft: theme.spacing(0.5),\n marginTop: Distances.HALF_FIELD_20,\n },\n '& .MuiFormControlLabel-label': {\n marginLeft: theme.spacing(1),\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '14px',\n },\n },\n buttonWrapper: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'end',\n [theme.breakpoints.down(1500)]: {\n flexDirection: 'column',\n justifyContent: 'center',\n },\n },\n button: {\n width: '210px',\n margin: '0',\n marginTop: Distances.HALF_FIELD_20,\n marginBottom: Distances.HALF_FIELD_20,\n marginLeft: Distances.HALF_FIELD_20,\n },\n linkColor: {\n color: theme.palette.accentGreen.main,\n },\n }),\n);\n\nexport default useStyles;\n","import {\n Box,\n Checkbox,\n DialogActions,\n FormControlLabel,\n FormGroup,\n Typography,\n} from '@mui/material';\nimport { clsx } from 'clsx';\nimport React, { ChangeEvent, useContext, useState, useEffect } from 'react';\nimport { Link as RouterLink, useLocation } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport routes from '../../routes';\nimport { CookieContext } from '../../util/global-context';\nimport MPButton2 from '../button/MPButton2';\nimport useStyles from './CookieBanner.styles';\nimport {\n CheckboxStyleProps,\n useSharedCheckboxStyles,\n} from '../../styles/checkbox.styles';\n\ninterface CookieModalProps {\n onAll: () => void;\n onSelected: () => void;\n}\n\nconst CookieBanner: React.FC = (props) => {\n const { statisticCookie, setStatisticCookieContext } =\n useContext(CookieContext);\n const [sidebarDisplayed, setSidebarDisplayed] = useState(false);\n const { t } = useTranslation();\n const classes = useStyles();\n const checkboxStyleProps: CheckboxStyleProps = { isGreen: true, isSmall: true};\n const sharedCheckboxClasses = useSharedCheckboxStyles(checkboxStyleProps);\n const location = useLocation();\n\n const handleSelectCookies = (event: ChangeEvent) => {\n //currently we just have cookies for statistics.\n //add logic here, if further cookies added\n if (event.target.checked) {\n setStatisticCookieContext(true);\n } else {\n setStatisticCookieContext(false);\n }\n };\n useEffect(() => {\n if (\n location.pathname.includes('/checkout') ||\n location.pathname.includes(routes.dashboard.base)\n ) {\n setSidebarDisplayed(false);\n } else {\n setSidebarDisplayed(true);\n }\n }, [location]);\n\n return (\n \n \n \n {t('weValueYourPrivacy')}\n \n {t('cookieShortText')}\n \n \n {t('readMore')}\n \n \n \n \n \n \n }\n className={classes.formLabel}\n label={t(`necessary`)}\n />\n \n }\n className={classes.formLabel}\n label={t(`statistics`)}\n />\n \n \n \n \n {\n setStatisticCookieContext(statisticCookie);\n props.onSelected();\n }}\n >\n {t('acceptSelected')}\n \n {\n props.onAll();\n }}\n >\n {t('acceptAll')}\n \n \n \n \n );\n};\n\nexport default CookieBanner;\n","import { Theme } from '@mui/material/styles';\n\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n footer: {\n position: 'absolute',\n width: '100%',\n fontFamily: theme.typography.fontFamily,\n backgroundColor: theme.palette.grey[800],\n color: 'white',\n bottom: 0,\n paddingTop: theme.spacing(0.4),\n paddingBottom: theme.spacing(0.4),\n display: 'flex',\n justifyContent: 'space-between',\n [theme.breakpoints.down('md')]: {\n display: 'flex',\n flexDirection: 'column',\n },\n //same values used in App.css for the #content margins\n paddingLeft: '77px',\n paddingRight: '77px',\n },\n companyNameItem: {\n lineHeight: '25px',\n fontSize: '0.8rem',\n textAlign: 'center',\n fontWeight: 300\n },\n linksContainer: {\n lineHeight: '25px',\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-evenly',\n width: 'fit-content',\n fontWeight: 300,\n [theme.breakpoints.down('md')]: {\n marginTop: theme.spacing(1.5),\n width: '100%',\n },\n },\n linkWrapper: {\n display: 'flex',\n maxWidth: 'fit-content',\n [theme.breakpoints.down('md')]: {\n maxWidth: '100%',\n justifyContent: 'center',\n },\n },\n link: {\n display: 'block',\n alignSelf: 'center',\n fontSize: '0.8rem',\n color: 'white',\n textDecoration: 'none',\n width: 'max-content',\n '&:hover': {\n textDecoration: 'underline !important',\n },\n },\n divider: {\n backgroundColor: 'white',\n height: '100%',\n fontSize: '0.8rem',\n margin: '9px',\n display: 'inline',\n },\n })\n);\n\nexport default useStyles;\n","import React from 'react';\nimport { Box, Divider, Grid, Hidden, Typography } from '@mui/material';\nimport { Link as RouterLink } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport routes from '../../routes';\nimport useStyles from './Footer.styles';\n\nconst Footer: React.FC = () => {\n const classes = useStyles();\n const { t } = useTranslation();\n\n interface FooterLink {\n translationKey: string;\n route: string;\n }\n\n const footerLinks: FooterLink[] = [\n { translationKey: 'termsOfUse', route: routes.termsOfUse },\n { translationKey: 'dataPrivacy', route: routes.dataPrivacy },\n { translationKey: 'imprint', route: routes.imprint },\n ];\n\n const generateFooterLink = (\n route: string,\n translationKey: string,\n hasDivider: boolean,\n mdColumns: number\n ) => (\n \n \n {t(translationKey)}\n \n \n \n \n \n \n \n );\n\n return (\n \n \n ©msg systems ag {new Date().getFullYear()}\n \n \n {footerLinks.map((footerLink, index) =>\n generateFooterLink(\n footerLink.route,\n footerLink.translationKey,\n index < footerLinks.length - 1,\n Math.floor(12 / footerLinks.length)\n )\n )}\n \n \n );\n};\n\nexport default Footer;\n","import axios from '../httpClient';\nimport { NUMBER_OF_NOTIFICATIONS_IN_ONE_BATCH } from '../../constants/constants';\nimport { NotificationDataType } from '../../models/userNotification';\nimport {\n authScopes,\n getCurrentAccount,\n acquireTokenSilentOrRefreshToken,\n} from '../auth';\nimport { appConfiguration } from '../../configuration';\n\nclass UserNotificationsService {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl;\n }\n\n async getUnreadNotificationsCount(partnerId: string): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return (\n await axios.get(`${this.baseUrl}/notifications/count`, {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n params: {\n partnerId: partnerId,\n },\n })\n ).data.count;\n }\n\n async getBatchOfUserNotifications(\n partnerId: string,\n page: number\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n return (\n await axios.get(`${this.baseUrl}/notifications/`, {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n params: {\n partnerId: partnerId,\n page: page,\n size: NUMBER_OF_NOTIFICATIONS_IN_ONE_BATCH,\n },\n })\n ).data;\n }\n\n async markAllNotificationsAsRead(\n partnerId: string,\n latestNotificationTimestamp: number\n ) {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return axios.put(`${this.baseUrl}/notifications/read`, null, {\n headers: {\n Authorization: `Bearer ${authResult.idToken}`,\n },\n params: {\n partnerId: partnerId,\n timestamp: latestNotificationTimestamp,\n },\n });\n }\n\n async archiveUserNotification(partnerId: string, notificationId: string) {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return axios.put(`${this.baseUrl}/notifications/archive`, null, {\n headers: {\n Authorization: `Bearer ${authResult.idToken}`,\n },\n params: {\n partnerId: partnerId,\n notificationId: notificationId,\n },\n });\n }\n}\n\nexport const notificationService = new UserNotificationsService(\n appConfiguration()?.coreApiUrl ?? ''\n);\n","import { Theme } from '@mui/material/styles';\n\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n activeLanguage: {\n fontWeight: 'bold',\n color: `${theme.palette.primary.main} !important`,\n },\n language: {\n '&:hover': {\n backgroundColor: 'transparent',\n },\n minWidth: '34px',\n padding: '5px',\n fontSize: '18px',\n lineHeight: '100%',\n color: theme.palette.grey[900],\n [theme.breakpoints.down('xl')]: {\n fontSize: '16px !important',\n },\n },\n })\n);\nexport default useStyles;\n","import React, { useState } from 'react';\nimport Button from '@mui/material/Button';\nimport { supportedLngs } from '../../i18n';\nimport useStyles from './LanguageMenu.styles';\nimport { Box } from '@mui/material';\nimport { useTranslation } from 'react-i18next';\n\nconst LanguageMenu: React.FC = () => {\n const classes = useStyles();\n const { t, i18n } = useTranslation();\n const defaultLanguageIndex = supportedLngs.findIndex(\n (l) => l.key === i18n.language\n );\n const [selectedIndex, setSelectedIndex] = useState(defaultLanguageIndex);\n\n const handleLanguageItemClick = async (index: number) => {\n setSelectedIndex(index);\n await i18n.changeLanguage(supportedLngs[index].key);\n };\n\n return (\n \n {supportedLngs.map((_option, index) => (\n \n ))}\n \n );\n};\n\nexport default LanguageMenu;\n","import { Theme } from '@mui/material/styles';\n\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n appBar: {\n position: 'sticky',\n height: 'inherit',\n zIndex: theme.zIndex.drawer + 1,\n backgroundColor: theme.palette.white.main,\n color: theme.palette.typography.main,\n whiteSpace: 'nowrap',\n transition: 'all 0.5s',\n boxShadow: '0px 3px 5px 0px rgb(0 0 0 / 10%);',\n },\n container: {\n height: '100%',\n maxWidth: '2090px !important',\n },\n leftAndRight: {\n height: '45px',\n paddingRight: '54px',\n alignItems: 'center',\n paddingBottom: '50px',\n paddingTop: '5px',\n },\n toolbar: {\n height: '100%',\n },\n leftPart: {\n paddingLeft: '54px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'start',\n },\n rightPart: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'end',\n minHeight: '45px',\n },\n backButtonIcon: {\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n border: '1px solid',\n borderColor: theme.palette.border.main,\n marginRight: '10px',\n },\n backButtonLink: {\n textDecoration: 'none',\n color: theme.palette.typography.main,\n },\n activeMenuButton: {\n borderBottom: `2px ${theme.palette.primary.main} solid`,\n transition: 'none',\n borderRadius: 0,\n },\n logoLabel: {\n marginLeft: '9px',\n color: theme.palette.grey[800],\n textTransform: 'none',\n fontSize: '25px',\n },\n logoButton: {\n color: 'transparent !important',\n paddingLeft: 0,\n '&:hover': {\n backgroundColor: 'transparent',\n },\n },\n rightNavbarContent: {\n textAlign: 'right',\n },\n searchButton: {\n marginRight: '36px',\n display: 'none',\n },\n languageMenu: {\n marginRight: '22px',\n },\n notificationBellIcon: {\n color: theme.palette.darkGrey.main,\n zIndex: 1,\n },\n notificationBadge: {\n backgroundColor: theme.palette.secondary.dark,\n color: 'white',\n transform: `translate(${40}%,-${25}%)`,\n paddingTop: '1px',\n height: '18px',\n width: '18px',\n minWidth: '18px',\n [theme.breakpoints.down('xl')]: {\n paddingTop: 0,\n },\n },\n notificationCenter: {\n borderTopLeftRadius: '24px',\n borderBottomLeftRadius: '24px',\n position: 'fixed',\n top: '76px',\n right: 0,\n width: '337px',\n height: '766px',\n backgroundColor: 'white',\n zIndex: 1250,\n boxShadow:\n '0px 0px 1px rgb(48 49 51 / 10%), 0px 4px 8px rgb(48 49 51 / 15%)',\n [theme.breakpoints.down('xl')]: {\n top: '58px',\n height: '591px',\n },\n overflowY: 'scroll',\n '&::-webkit-scrollbar': {\n width: '6px',\n },\n '&::-webkit-scrollbar-track': {\n boxShadow: 'inset 0 0 0',\n borderRadius: '10px',\n },\n '&::-webkit-scrollbar-thumb': {\n backgroundColor: '#7F7F7F',\n borderRadius: '10px',\n '&:hover': {\n border: `1px solid ${theme.palette.secondary.main}`,\n },\n },\n },\n settingIcon: {\n display: 'none',\n position: 'absolute',\n right: '18px',\n top: '9px',\n [theme.breakpoints.down('xl')]: {\n right: '12px',\n },\n },\n notificationCenterTitle: {\n fontSize: '14px',\n fontWeight: 700,\n position: 'relative',\n top: '20px',\n left: '27px',\n height: '54px',\n },\n notificationWrapper: {\n width: '100%',\n borderTop: '2px solid #EBEBEB',\n '&:first-child': {\n borderTop: 'none',\n },\n },\n notificationBox: {\n width: '100%',\n },\n unreadNotificaton: {\n backgroundColor: 'rgb(160, 200, 215, 0.15)',\n },\n notificationLabel: {\n color: 'white',\n borderRadius: '60px',\n position: 'relative',\n top: '11px',\n left: '27px',\n paddingLeft: '14px',\n fontSize: '12px',\n },\n criticalNotificationLabel: {\n backgroundColor: theme.palette.primary.main,\n width: '78px',\n },\n importantNotificationLabel: {\n backgroundColor: '#D08B01',\n width: '93px',\n },\n informativeNotificationLabel: {\n backgroundColor: theme.palette.secondary.main,\n width: '104px',\n },\n notificationDate: {\n position: 'relative',\n top: '12px',\n left: '18px',\n color: theme.palette.grey.A200,\n fontSize: '12px',\n },\n closeNotificationIconButton: {\n position: 'relative',\n left: '9px',\n [theme.breakpoints.down('xl')]: {\n left: '5px',\n },\n },\n closeNotification: {\n fontSize: '18px',\n color: theme.palette.darkGrey.main,\n },\n notificationTitle: {\n position: 'relative',\n left: '27px',\n fontWeight: 700,\n width: '85%',\n wordBreak: 'break-all',\n },\n notificationDescription: {\n position: 'relative',\n left: '27px',\n fontWeight: 400,\n wordBreak: 'break-word',\n width: '85%',\n marginTop: '3px',\n marginBottom: '9px',\n },\n infiniteScroll: {\n height: '800px',\n overflow: 'hidden',\n },\n emptyNotificationCenter: {\n position: 'relative',\n left: '27px',\n marginTop: '9px',\n },\n notificationButton: {\n padding: '0px',\n marginRight: '5px',\n marginLeft: '14px',\n marginBottom: '5px',\n width: '30px',\n },\n hideNavigationLink: {\n display: 'none',\n },\n })\n);\nexport default useStyles;\n","import { Theme } from '@mui/material/styles';\n\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n notificationWrapper: {\n width: '100%',\n borderTop: '1px solid #EBEBEB',\n '&:first-child': {\n borderTop: 'none',\n },\n '&:hover': {\n backgroundColor: 'rgba(0, 0, 0, 0.04)',\n cursor: 'pointer',\n },\n },\n unreadNotificaton: {\n backgroundColor: 'rgb(160, 200, 215, 0.15)',\n },\n notificationLabel: {\n color: 'white',\n borderRadius: '60px',\n position: 'relative',\n top: '12px',\n left: '30px',\n paddingLeft: '15px',\n paddingRight: '15px',\n },\n criticalNotificationLabel: {\n backgroundColor: theme.palette.primary.main,\n },\n importantNotificationLabel: {\n backgroundColor: '#D08B01',\n },\n informativeNotificationLabel: {\n backgroundColor: theme.palette.secondary.main,\n },\n notificationDate: {\n position: 'relative',\n top: '10px',\n left: '10px',\n color: theme.palette.grey.A200,\n fontSize: '10px',\n },\n closeNotificationIconButton: {\n position: 'relative',\n left: '10px',\n marginTop: '13px',\n padding: '5px',\n [theme.breakpoints.down('xl')]: {\n left: '6px',\n },\n },\n closeNotification: {\n fontSize: '20px',\n color: theme.palette.darkGrey.main,\n },\n notificationTitle: {\n position: 'relative',\n left: '30px',\n fontWeight: 700,\n width: '85%',\n wordBreak: 'break-all',\n },\n notificationDescription: {\n position: 'relative',\n left: '30px',\n fontWeight: 400,\n wordBreak: 'break-word',\n width: '85%',\n marginTop: '3px',\n marginBottom: '10px',\n },\n })\n);\nexport default useStyles;\n","import React from 'react';\nimport { Box, Grid, IconButton, Typography } from '@mui/material';\nimport CloseIcon from '@mui/icons-material/Close';\nimport { clsx } from 'clsx';\nimport { useHistory } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport {\n NotificationReadStatus,\n NotificationSeverityType,\n} from '../../../models/enums';\nimport NotificationCardProps from './NotificationCardProps';\nimport useStyles from './MPNotificationCard.styles';\nimport {\n checkIfNotificationWasCreatedToday,\n convertUnixTimestampToDateAndTime,\n convertUnixTimestampToTime,\n} from '../../../util/date-time';\nimport { determineNotificationSourceURL } from '../../../util/util';\n\nconst MPNotificationCard: React.FC = ({\n userNotification,\n onClick,\n onDismiss,\n}) => {\n const { t } = useTranslation();\n const classes = useStyles();\n const history = useHistory();\n\n const formatNotificationDate = (createdAt: number) => {\n if (checkIfNotificationWasCreatedToday(createdAt)) {\n const time = convertUnixTimestampToTime(createdAt);\n return t('today').concat(' | ').concat(time);\n } else {\n return convertUnixTimestampToDateAndTime(createdAt).replace(/, /, ' | ');\n }\n };\n\n const handleNotificationClick = () => {\n history.push(determineNotificationSourceURL(userNotification));\n onClick();\n };\n\n const handleNotificationDismiss = (event: any) => {\n event.preventDefault();\n event.stopPropagation();\n onDismiss(userNotification.id);\n };\n\n return (\n \n \n \n \n {userNotification.severityType}\n \n \n \n \n {formatNotificationDate(userNotification.createdAt)}\n \n \n \n \n \n \n \n \n \n \n {t(userNotification.data.title)}\n \n \n \n \n {t(userNotification.data.description, {\n serviceName: userNotification.data.productName,\n companyName: userNotification.data.partnerName,\n })}\n \n \n \n );\n};\n\nexport default MPNotificationCard;\n","import { Theme } from '@mui/material/styles';\n\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\nimport { Distances } from '../../../../AppTheme';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n menuItem: {\n backgroundColor: 'transparent !important',\n cursor: 'default',\n },\n profileButton: {\n backgroundColor: theme.palette.primary.main,\n borderRadius: '1000px',\n textTransform: 'none',\n paddingLeft: '10px',\n paddingRight: '10px',\n '&:hover': {\n backgroundColor: theme.palette.primary.dark,\n },\n height: '36px',\n },\n profileImage: {\n borderRadius: '50%',\n border: '2px solid white',\n marginRight: theme.spacing(1),\n width: '21px',\n height: '21px',\n overflow: 'auto',\n backgroundColor: 'white',\n display: 'none',\n },\n profilePicturePlaceholder: {\n width: '21px',\n height: '21px',\n backgroundColor: 'rgba(255, 255, 255, 0.25)',\n fontSize: '11px',\n borderRadius: '13px',\n marginRight: '8px',\n color: '#FFFFFF',\n padding: '1px 0px',\n },\n profileName: {\n fontSize: '13px',\n lineHeight: Distances.HALF_FIELD_20,\n color: 'white',\n },\n displayNone: {\n display: 'none',\n },\n })\n);\nexport default useStyles;\n","import React, { useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport { useTranslation } from 'react-i18next';\nimport {\n partnerCurrentPartner,\n userSelector,\n} from '../../../../store/selectors';\nimport { Link } from 'react-router-dom';\nimport routes from '../../../../routes';\nimport {\n Menu,\n MenuItem,\n Divider,\n Typography,\n Box,\n Button,\n} from '@mui/material';\nimport useStyles from './UserMenu.styles';\n\ninterface UserMenuProps {\n logout: () => void;\n}\n\nconst UserMenu = ({ logout }: UserMenuProps) => {\n const classes = useStyles();\n const user = useSelector(userSelector);\n const { t } = useTranslation();\n const [anchorEl, setAnchorEl] = useState(null);\n const partner = useSelector(partnerCurrentPartner);\n\n const showMenu = (event: React.MouseEvent) => {\n setAnchorEl(event.currentTarget);\n };\n\n const handleClose = () => {\n setAnchorEl(null);\n };\n\n const handleLogout = () => {\n handleClose();\n logout();\n };\n\n return !!user ? (\n \n \n \n \n ) : (\n \n );\n};\n\nexport default UserMenu;\n","import { Theme } from '@mui/material/styles';\n\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n loginButton: {\n padding: '5px',\n textTransform: 'uppercase',\n color: theme.palette.grey[900],\n fontSize: '20px',\n lineHeight: '100% !important',\n [theme.breakpoints.down('xl')]: {\n fontSize: '16px !important',\n },\n },\n })\n);\nexport default useStyles;\n","import React from 'react';\nimport { Box, Hidden, Button, MenuItem } from '@mui/material';\nimport { useTranslation } from 'react-i18next';\nimport { handleLogin } from '../../../../services/auth';\nimport useStyles from './Login.styles';\n\nconst Login: React.FC = () => {\n const classes = useStyles();\n const { t, i18n } = useTranslation();\n\n return (\n \n \n \n \n\n \n \n \n \n );\n};\n\nexport default Login;\n","import React, { useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport {\n loadUserPartners,\n setUserPartners,\n} from '../../../store/actions/partnerActions';\nimport { tokenAcquiredSelector, userSelector } from '../../../store/selectors';\nimport UserMenu from './user-menu/UserMenu';\nimport {\n AuthenticatedTemplate,\n UnauthenticatedTemplate,\n} from '@azure/msal-react';\nimport { handleLogout } from '../../../services/auth';\nimport Login from './login/Login';\n\nconst SignInSignUp: React.FC = () => {\n const dispatch = useDispatch();\n const user = useSelector(userSelector);\n const tokenAcquired = useSelector(tokenAcquiredSelector);\n\n useEffect(() => {\n if (user) {\n dispatch(loadUserPartners());\n } else {\n dispatch(setUserPartners([]));\n }\n }, [dispatch, user]);\n\n return (\n <>\n \n {tokenAcquired ? (\n \n ) : (\n \n )}\n \n \n \n \n >\n );\n};\n\nexport default SignInSignUp;\n","import { appConfiguration } from '.';\n\nexport const getLocalPicturePath = (path: string) =>\n appConfiguration()?.local?.picturePath\n ? `/env/${appConfiguration()?.local?.picturePath}${path}`\n : path;\n","import { AuthenticatedTemplate } from '@azure/msal-react';\nimport MenuIcon from '@mui/icons-material/Menu';\nimport {\n AppBar,\n Badge,\n Box,\n Button,\n ClickAwayListener,\n Container,\n Divider,\n Grid,\n Hidden,\n IconButton,\n Menu,\n MenuItem,\n Toolbar,\n Typography,\n} from '@mui/material';\nimport React, { useEffect, useState } from 'react';\nimport InfiniteScroll from 'react-infinite-scroll-component';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Link, useLocation } from 'react-router-dom';\nimport { NUMBER_OF_NOTIFICATIONS_IN_ONE_BATCH } from '../../constants/constants';\nimport { useTranslation } from 'react-i18next';\nimport { supportedLngs } from '../../i18n';\nimport routes from '../../routes';\nimport {\n archiveUserNotification,\n loadBatchOfUserNotifications,\n markAllNotificationsAsRead,\n updateHasMorePages,\n} from '../../store/actions/userNotificationsActions';\nimport {\n notificationCurrentPageSelector,\n notificationhasMorePagesSelector,\n notificationsNumberSelector,\n notificationsSelector,\n notificationsUnreadSelector,\n partnerCurrentPartner,\n partnerDashboardCreateState,\n} from '../../store/selectors';\nimport { openContact } from '../contact-form/ContactFormOverlay';\nimport LanguageMenu from '../language-menu/LanguageMenu';\nimport LoadingIndicator from '../loading/Loading';\nimport useStyles from './NavigationBar.styles';\nimport MPNotificationCard from './notification/MPNotificationCard';\nimport SignInSignUp from './signin-signup/SignInSignUp';\nimport { getLocalPicturePath } from '../../configuration/local-dev-utils';\nimport {\n setCurrentPartner,\n setDashboardPartnerCreate,\n} from '../../store/actions/partnerActions';\nimport { localService } from '../../services/localService';\n\nexport const NavigationBar: React.FC = () => {\n const classes = useStyles();\n const { t, i18n } = useTranslation();\n const dispatch = useDispatch();\n const currentPartner = useSelector(partnerCurrentPartner);\n const currentPage = useSelector(notificationCurrentPageSelector);\n const hasMoreNotifications = useSelector(notificationhasMorePagesSelector);\n const numberOfNotificationsInLastBatch = useSelector(\n notificationsNumberSelector\n );\n const dashboardPartnerCreate = useSelector(partnerDashboardCreateState);\n\n const handleClickOutsideNotifications = () => {\n if (isNotificationCenterOpen) {\n setIsNotificationCenterOpen(false);\n markNotificationsAsRead();\n }\n };\n\n const mobileMenuId = 'app-menu-mobile';\n const location = useLocation();\n const route = location.pathname;\n\n const noSidebarDisplayed =\n location.pathname.includes('/checkout') ||\n location.pathname.includes('/service/') ||\n location.pathname.includes(routes.dashboard.base);\n\n const [mobileMenuAnchorEl, setMobileMenuAnchorEl] =\n useState(null);\n\n const [backIconPath, setBackIconPath] = useState();\n const [backNavigationPath, setBackNavigationPath] = useState('');\n const [backNavigationText, setBackNavigationText] = useState('');\n\n useEffect(() => {\n setBackIconPath(\n location.pathname.includes(routes.dashboard.base)\n ? '/icons/sidebar/all_solutions_red.svg'\n : '/icons/arrow_left_yellow.svg'\n );\n setBackNavigationText(\n location.pathname.includes(routes.dashboard.base)\n ? 'goToAllSolutions'\n : 'backAllSolutions'\n );\n setBackNavigationPath((previous) => {\n if (\n location.pathname.includes('/service') ||\n location.pathname.includes('/checkout')\n ) {\n if (previous) {\n return previous;\n } else {\n return routes.productCatalog;\n }\n } else {\n if (location.pathname.includes(routes.dashboard.base)) {\n return routes.productCatalog;\n } else {\n if (location.search) {\n return location.pathname + location.search;\n } else {\n return location.pathname;\n }\n }\n }\n });\n }, [location]);\n\n const isMobileMenuOpen = Boolean(mobileMenuAnchorEl);\n\n const handleMobileMenuOpen = (event: React.MouseEvent) => {\n setMobileMenuAnchorEl(event.currentTarget);\n };\n\n const handleMobileMenuClose = () => {\n setMobileMenuAnchorEl(null);\n };\n\n const handleLanguageItemClick = async (index: number) => {\n setSelectedIndex(index);\n await i18n.changeLanguage(supportedLngs[index].key);\n };\n\n const defaultLanguageIndex = supportedLngs.findIndex(\n (l) => l.key === i18n.language\n );\n const [selectedIndex, setSelectedIndex] = useState(defaultLanguageIndex);\n\n const [isNotificationCenterOpen, setIsNotificationCenterOpen] =\n useState(false);\n\n const numberOfUndreadNotifications = useSelector(notificationsUnreadSelector);\n\n const userNotifications = Object.values(\n useSelector(notificationsSelector)\n ).sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1));\n\n const markNotificationsAsRead = () => {\n if (!currentPartner) {\n return;\n }\n\n if (isNotificationCenterOpen && userNotifications.length >= 1) {\n dispatch(\n markAllNotificationsAsRead(\n currentPartner.id,\n userNotifications[0].createdAt\n )\n );\n }\n };\n\n const handleNotifCenterDisplay = () => {\n if (currentPartner) {\n markNotificationsAsRead();\n\n if (!isNotificationCenterOpen) {\n dispatch(updateHasMorePages(true));\n }\n }\n\n setIsNotificationCenterOpen(!isNotificationCenterOpen);\n };\n\n const dismissNotification = (notificationId: string) => {\n if (currentPartner) {\n dispatch(archiveUserNotification(currentPartner.id, notificationId));\n }\n };\n\n const fetchMoreData = () => {\n if (currentPartner && currentPartner.id) {\n if (\n numberOfNotificationsInLastBatch < NUMBER_OF_NOTIFICATIONS_IN_ONE_BATCH\n ) {\n dispatch(updateHasMorePages(false));\n }\n dispatch(loadBatchOfUserNotifications(currentPartner.id, currentPage));\n }\n return;\n };\n\n const onCancelPartnerCreation = () => {\n if (dashboardPartnerCreate) {\n dispatch(setDashboardPartnerCreate(false));\n const previousPartner = localService.getCurrentPartner();\n if (previousPartner) {\n dispatch(setCurrentPartner(previousPartner));\n }\n }\n };\n\n return (\n <>\n \n \n \n \n \n \n {noSidebarDisplayed && (\n \n {\n onCancelPartnerCreation();\n }}\n >\n
\n \n {\n onCancelPartnerCreation();\n }}\n >\n {t(backNavigationText)}\n \n \n )}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n \n \n \n \n\n \n \n\n \n \n \n\n \n \n \n \n \n\n {isNotificationCenterOpen && (\n \n \n {userNotifications.length > 0 ? (\n <>\n \n \n \n {t('notificationCenter')}\n \n \n \n \n \n
\n \n \n \n \n \n \n \n }\n className={classes.infiniteScroll}\n scrollableTarget=\"notification-center\"\n >\n {Object.values(userNotifications).map(\n (userNotification) => (\n \n )\n )}\n \n \n \n >\n ) : (\n <>\n \n \n \n {t('notificationCenter')}\n \n \n \n \n {t('noNotificationsYet')}\n \n \n \n >\n )}\n \n \n )}\n >\n );\n};\n","import { useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nexport default function ScrollToTop() {\n const { pathname } = useLocation();\n useEffect(() => {\n window.onscroll = () => {\n window.scrollTo({\n top: 0,\n });\n };\n setTimeout(() => {\n window.onscroll = () => {\n //this is intentional, but try removing the onscroll, and scrolling in the app :D \n };\n }, 30);\n window.scrollTo({\n top: 0,\n behavior: 'auto',\n });\n }, [pathname]);\n\n return null;\n}\n","import { Theme } from '@mui/material/styles';\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\nimport { Distances } from '../../AppTheme';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n sidebar: {\n position: 'fixed',\n display: 'flex',\n flexDirection: 'column',\n width: 'inherit',\n height: '100%',\n paddingLeft: Distances.HALF_FIELD_30,\n paddingTop: Distances.HALF_FIELD_20,\n background: theme.palette.primary.main,\n overflowY: 'auto',\n overflowX: 'hidden',\n zIndex: 100 //should be higher than top navBar, so it can't overlap\n },\n logoButton: {\n color: 'transparent !important',\n paddingLeft: 0,\n '&:hover': {\n backgroundColor: 'transparent',\n },\n },\n marginBottomMedium: {\n marginBottom: Distances.FIELD,\n },\n headline: {\n marginBottom: Distances.INPUT,\n color: theme.palette.lightRed.main,\n },\n menuItemButton: {\n display: 'block',\n width: '100%',\n padding: Distances.HALF_FIELD_20,\n borderRadius: '10px 0px 0px 10px',\n textAlign: 'left',\n textTransform: 'none',\n color: theme.palette.white.main,\n '&:hover': {\n background: theme.palette.accentRed.main,\n },\n '& > span': {\n display: 'flex',\n },\n },\n menuItemTypography: {\n alignItems: 'center',\n },\n menuItemIcon: {\n marginRight: '7px',\n },\n focus: {\n backgroundColor: theme.palette.primary.dark,\n filter: 'brightness(130%)',\n },\n\n containerContact: {\n marginTop: 'auto',\n bottom: 0,\n width: '180px',\n height: '112px',\n marginRight: Distances.HALF_FIELD_30,\n borderRadius: '10px',\n color: theme.palette.white.main,\n background: theme.palette.accentRed.main,\n marginBottom: Distances.HALF_FIELD_30,\n },\n contentContact: {\n marginTop: 'auto',\n bottom: '52px',\n position: 'relative',\n display: 'grid',\n alignItems: 'center',\n justifyContent: 'center',\n textAlign: 'center',\n color: theme.palette.white.main,\n },\n typographyContact: {\n marginBottom: Distances.INPUT,\n fontWeight:'400',\n },\n questionIcon: {\n position: 'relative',\n top: '-33px',\n bottom: '-36px',\n left: '58px',\n },\n })\n);\n\nexport default useStyles;\n","import { AuthenticatedTemplate } from '@azure/msal-react';\nimport { Box, Button, Typography } from '@mui/material';\nimport { clsx } from 'clsx';\nimport { Dictionary } from 'lodash';\nimport React, { useEffect, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link, useLocation } from 'react-router-dom';\nimport { getLocalPicturePath } from '../../configuration/local-dev-utils';\nimport routes from '../../routes';\nimport MPButton2 from '../button/MPButton2';\nimport { openContact } from '../contact-form/ContactFormOverlay';\nimport useStyles from './Sidebar.styles';\n\ninterface SidebarSection {\n key: string;\n iconPath?: string;\n toPath: string;\n}\n\nenum SidebarSections {\n HOME = 'HOME',\n ABOUT = 'ABOUT',\n DASHBOARD = 'DASHBOARD',\n ALL_SOLUTIONS = 'ALL_SOLUTIONS',\n}\n\nconst Sidebar: React.FC = () => {\n const { t } = useTranslation();\n const classes = useStyles();\n const location = useLocation();\n const route = location.pathname;\n\n const [sidebarConfig, setSidebarConfig] = useState<\n Dictionary\n >({\n [SidebarSections.HOME]: {\n key: 'home',\n toPath: routes.home,\n },\n // [SidebarSections.ABOUT]: {\n // key: 'about',\n // toPath: routes.ourVision,\n // }, // will be used again later\n [SidebarSections.DASHBOARD]: {\n key: 'dashboard',\n iconPath: '/icons/sidebar/dashboard.svg',\n toPath: routes.dashboard.base,\n },\n [SidebarSections.ALL_SOLUTIONS]: {\n key: 'allSolutions',\n toPath: routes.productCatalog,\n },\n });\n\n useEffect(() => {\n setSidebarConfig({\n ...sidebarConfig,\n // [SidebarSections.ABOUT]: {\n // ...sidebarConfig[SidebarSections.ABOUT],\n // iconPath:\n // location.pathname === routes.ourVision\n // ? '/icons/sidebar/our_vision_WHITE.svg'\n // : '/icons/sidebar/our_vision.svg',\n // }, // will be used again later\n [SidebarSections.HOME]: {\n ...sidebarConfig[SidebarSections.HOME],\n iconPath:\n location.pathname === routes.home\n ? '/icons/sidebar/home_WHITE.svg'\n : '/icons/sidebar/home.svg',\n },\n [SidebarSections.ALL_SOLUTIONS]: {\n ...sidebarConfig[SidebarSections.ALL_SOLUTIONS],\n iconPath:\n location.pathname === routes.productCatalog\n ? '/icons/sidebar/all_solutions_WHITE.svg'\n : '/icons/sidebar/all_solutions.svg',\n },\n });\n // sidebarConfig will not be added to the dependency array, since it causes an infinite loop\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [location]);\n\n return (\n sidebarConfig && (\n \n \n \n \n \n \n {t('start')}\n \n \n {/* // will be used again later*/}\n \n \n \n \n \n \n {t('solutions')}\n \n \n \n \n
\n \n \n {t('questions')}\n \n openContact()}>\n {t('contactUs')}\n \n \n \n \n )\n );\n};\n\nexport default Sidebar;\n","import * as signalR from '@microsoft/signalr';\nimport { appConfiguration } from '../configuration';\nimport { SignalRChannel } from '../models/enums';\nimport { authScopes, getCurrentAccount, msalPca } from './auth';\n\ntype NotificationHandler = (data: any) => void;\n\nclass NotificationService {\n private _connection: signalR.HubConnection;\n private _connectionEstablished = false;\n public partnerId: string;\n public userId: string;\n\n constructor(partnerId: string, userId: string) {\n this.partnerId = partnerId;\n this.userId = userId;\n this._connection = new signalR.HubConnectionBuilder()\n .withUrl(`${appConfiguration()?.coreApiUrl}/notifications`, {\n accessTokenFactory: async () =>\n (\n await msalPca.acquireTokenSilent({\n scopes: authScopes,\n account: getCurrentAccount(),\n })\n ).idToken,\n headers: {\n 'partner-id': this.partnerId,\n 'user-id': this.userId,\n },\n })\n .withAutomaticReconnect()\n .build();\n\n this._connection\n .start()\n .then(() => (this._connectionEstablished = true))\n .catch((e) =>\n console.log(`Could not setup notification connection: ${e.message | e}`)\n );\n\n this._connection.onclose((e) => {\n console.log(`SignalR connection closed. ${e?.message}`);\n });\n }\n\n get connectionEstablished(): boolean {\n return this._connectionEstablished;\n }\n\n registerSubscriptionHandler(handler: NotificationHandler) {\n this._connection.on(SignalRChannel.SUBSCRIPTIONS, handler);\n }\n\n clearSubscriptionHandler() {\n this._connection.off(SignalRChannel.SUBSCRIPTIONS);\n }\n\n registerPartnerHandler(handler: NotificationHandler) {\n this._connection.on(SignalRChannel.PARTNERS, handler);\n }\n\n clearPartnerHandler() {\n this._connection.off(SignalRChannel.PARTNERS);\n }\n\n registerUserNotificationHandler(handler: NotificationHandler) {\n this._connection.on(SignalRChannel.NOTIFICATIONS, handler);\n }\n\n clearUserNotificationHandler() {\n this._connection.off(SignalRChannel.NOTIFICATIONS);\n }\n\n registerProductHandler(handler: NotificationHandler) {\n this._connection.on(SignalRChannel.PRODUCTS, handler);\n }\n\n clearProductHandler() {\n this._connection.off(SignalRChannel.PRODUCTS);\n }\n\n close() {\n this._connection\n .stop()\n .catch((e) =>\n console.log(\n `There was an error on closing the connection: ${e.message | e}`\n )\n );\n this._connectionEstablished = false;\n }\n}\n\nlet notificationService: NotificationService;\n\nexport const getNotificationService = (partnerId: string, userId: string) => {\n notificationService =\n notificationService || new NotificationService(partnerId, userId);\n\n if (notificationService.partnerId !== partnerId) {\n notificationService.close();\n notificationService = new NotificationService(partnerId, userId);\n }\n return notificationService;\n};\n","import { AccountInfo } from '@azure/msal-browser';\n\nexport enum AuthActionTypes {\n LOGIN_SUCCESS = '[auth] Login success',\n AUTO_LOGIN = '[auth] Auto login',\n LOGOUT_SUCCESS = '[auth] Logout success',\n TOKEN_ACQUIRED = '[auth] Token acquired',\n}\n\ninterface LoginSuccessAction {\n type: AuthActionTypes;\n payload: AccountInfo;\n}\n\nexport const loginSuccess = (payload: AccountInfo): LoginSuccessAction => ({\n type: AuthActionTypes.LOGIN_SUCCESS,\n payload,\n});\n\ninterface AutoLoginAction {\n type: AuthActionTypes;\n payload: AccountInfo;\n}\n\nexport const autoLogin = (payload: AccountInfo): AutoLoginAction => ({\n type: AuthActionTypes.AUTO_LOGIN,\n payload,\n});\n\ninterface LogoutSuccessAction {\n type: AuthActionTypes;\n}\n\nexport const logoutSuccess = (): LogoutSuccessAction => ({\n type: AuthActionTypes.LOGOUT_SUCCESS,\n});\n\ninterface TokenAcquiredAction {\n type: AuthActionTypes;\n}\nexport const tokenAcquired = (): TokenAcquiredAction => ({\n type: AuthActionTypes.TOKEN_ACQUIRED,\n});\n","import { htmlHead as msgHtmlHead } from './msg/html-head';\nimport { htmlHead as inPunctoHtmlHead } from './inPuncto/html-head';\nimport { appConfiguration } from '..';\n\nconst htmlHeads: { [env: string]: any[] } = {\n msg: msgHtmlHead,\n inPuncto: inPunctoHtmlHead,\n};\n\nexport const htmlHead = htmlHeads[appConfiguration()?.htmlHeader || 'msg'];\n","/* eslint-disable react/jsx-key */\nimport React from 'react';\nimport { getLocalPicturePath } from '../../local-dev-utils';\n\nexport const htmlHead = [\n ,\n ,\n ,\n ,\n ,\n ,\n ,\n \n msg.Marketplace - Digital Products and Services for Your Business\n ,\n ,\n];\n","/* eslint-disable react/jsx-key */\nimport React from 'react';\nimport { getLocalPicturePath } from '../../local-dev-utils';\n\nexport const htmlHead = [\n ,\n ,\n ,\n ,\n ,\n ,\n ,\n Care for Innovation Marketplace,\n ,\n];\n","import { EffectCallback, useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useLocation } from 'react-router-dom';\nimport { ProductStatus, SignalRMessageType } from '../models/enums';\nimport Partner from '../models/partner';\nimport { Subscription } from '../models/subscription';\nimport { NotificationDataType } from '../models/userNotification';\nimport { getNotificationService } from '../services/notificationService';\nimport { setProductStatus } from '../store/actions/dashboardProductsActions';\nimport { setSignalRAlert } from '../store/actions/notificationsActions';\nimport { loadUserPartners, setPartner } from '../store/actions/partnerActions';\nimport { setSubscription } from '../store/actions/subscriptionsActions';\nimport { notificationReceivedSuccess } from '../store/actions/userNotificationsActions';\nimport { partnerCurrentPartner, userSelector } from '../store/selectors';\n\nexport const useNotifications: EffectCallback = () => {\n const location = useLocation();\n const user = useSelector(userSelector);\n const currentPartner = useSelector(partnerCurrentPartner);\n const dispatch = useDispatch();\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (!currentPartner || !user || !location) {\n return;\n }\n\n const handleSubscriptionNotifications = (data: {\n payload: Subscription;\n messageType: SignalRMessageType;\n }) => {\n const onSubscription = location.pathname.includes('subscriptions');\n\n if (data.payload.partnerId !== currentPartner.id) {\n return;\n }\n\n if (onSubscription) {\n dispatch(setSubscription(data.payload));\n }\n\n dispatch(\n setSignalRAlert({\n severity: 'success',\n messageKey: data.payload.productName,\n subscriptionId: data.payload.id,\n messageType: data.messageType,\n })\n );\n };\n\n getNotificationService(\n currentPartner.id,\n user.id\n ).registerSubscriptionHandler(handleSubscriptionNotifications);\n\n const handlePartnerNotifications = (data: {\n payload: Partner;\n messageType: SignalRMessageType;\n }) => {\n const onPartner = location.pathname.includes('partner');\n\n if (data.payload.id !== currentPartner.id) {\n return;\n }\n\n if (onPartner) {\n dispatch(setPartner(data.payload));\n }\n\n if (data.messageType === SignalRMessageType.PARTNER_UPDATED) {\n // Also update the current (user) partner (displayed in the menus)\n dispatch(loadUserPartners(data.payload.id));\n } else {\n dispatch(\n setSignalRAlert({\n severity: 'success',\n messageKey: '',\n subscriptionId: '',\n messageType: data.messageType,\n })\n );\n }\n };\n\n const handleUserNotifications = (data: {\n payload: NotificationDataType;\n messageType: SignalRMessageType;\n }) => {\n dispatch(notificationReceivedSuccess(data.payload));\n };\n\n getNotificationService(currentPartner.id, user.id).registerPartnerHandler(\n handlePartnerNotifications\n );\n\n getNotificationService(\n currentPartner.id,\n user.id\n ).registerUserNotificationHandler(handleUserNotifications);\n\n const handleProductNotifications = (data: {\n payload: { productId: string; partnerId: string; productName: string };\n messageType: SignalRMessageType;\n }) => {\n if (data.payload.partnerId !== currentPartner.id) {\n return;\n }\n\n const onServices = location.pathname.includes('products');\n\n switch (data.messageType) {\n case SignalRMessageType.PRODUCT_CREATION_FAILED:\n if (onServices) {\n dispatch(\n setProductStatus({\n productId: data.payload.productId,\n status: ProductStatus.FAILED,\n })\n );\n\n dispatch(\n setSignalRAlert({\n severity: 'error',\n messageKey: data.payload.productName,\n subscriptionId: '',\n messageType: data.messageType,\n })\n );\n }\n break;\n case SignalRMessageType.PRODUCT_CREATED:\n if (onServices) {\n dispatch(\n setProductStatus({\n productId: data.payload.productId,\n status: ProductStatus.ACTIVE,\n })\n );\n\n dispatch(\n setSignalRAlert({\n severity: 'success',\n messageKey: data.payload.productName,\n subscriptionId: '',\n messageType: data.messageType,\n })\n );\n }\n break;\n default:\n break;\n }\n };\n\n getNotificationService(currentPartner.id, user.id).registerProductHandler(\n handleProductNotifications\n );\n\n return () => {\n getNotificationService(\n currentPartner.id,\n user.id\n ).clearSubscriptionHandler();\n getNotificationService(currentPartner.id, user.id).clearPartnerHandler();\n getNotificationService(currentPartner.id, user.id).clearProductHandler();\n getNotificationService(\n currentPartner.id,\n user.id\n ).clearUserNotificationHandler();\n };\n }, [currentPartner, user, location, dispatch]);\n};\n","import { COOKIE_EXPIRATION_IN_MSEC } from '../../constants/constants';\n\nexport const getCookieValue = (name: string) => {\n const cookieList = decodeURIComponent(document.cookie).split(';');\n let cookieSettingValue = '';\n for (let i = 0; i < cookieList.length; i++) {\n let c = cookieList[i];\n while (c.charAt(0) == ' ') {\n c = c.substring(1);\n }\n if (c.indexOf(name) == 0) {\n cookieSettingValue = c.substring(name.length + 1, c.length);\n }\n }\n return cookieSettingValue;\n};\n\nconst getCookieExpirationDate = () => {\n const now = new Date();\n const time = now.getTime();\n const expireTime = time + COOKIE_EXPIRATION_IN_MSEC;\n now.setTime(expireTime);\n return now;\n};\n\nexport const setCookie = (name: string, value: string) => {\n const cookieExpirationDate = getCookieExpirationDate();\n document.cookie = `${name}=${encodeURIComponent(\n value\n )}; expires=${cookieExpirationDate.toUTCString()} path=/`;\n};\n\nexport const isCookieSet = (name: string) => {\n const cookieList = decodeURIComponent(document.cookie).split(';');\n let cookieSettingValue = '';\n for (let i = 0; i < cookieList.length; i++) {\n let c = cookieList[i];\n while (c.charAt(0) == ' ') {\n c = c.substring(1);\n }\n if (c.indexOf(name) == 0) {\n cookieSettingValue = c.substring(name.length + 1, c.length);\n }\n }\n return !!cookieSettingValue;\n};\n","import {\n COOKIE_ONLY_NECESSARY,\n COOKIE_USER_PREFERENCE,\n} from '../../constants/constants';\nimport { getCookieValue, isCookieSet, setCookie } from './cookie-repository';\n\nexport const isUserPreferenceCookieSet = () => {\n return isCookieSet(COOKIE_USER_PREFERENCE);\n};\n\nexport const setUserPreferenceCookie = (value: string) => {\n setCookie(COOKIE_USER_PREFERENCE, value);\n};\n\nexport const isCookieUseDisabledByUser = () => {\n const userPreferenceValue = getCookieValue(COOKIE_USER_PREFERENCE);\n if (\n userPreferenceValue === COOKIE_ONLY_NECESSARY ||\n userPreferenceValue === ''\n ) {\n return true;\n } else {\n return false;\n }\n};\n","import {\n AccountInfo,\n AuthenticationResult,\n AuthError,\n EventMessage,\n EventType,\n} from '@azure/msal-browser';\nimport { Box, Hidden } from '@mui/material';\nimport React, { lazy, Suspense, useEffect, useState } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Route, Switch, useLocation } from 'react-router-dom';\nimport MPAlert from './components/alert/MPAlert';\nimport ConfirmModal from './components/confirm-modal/ConfirmModal';\nimport ContactFormOverlay from './components/contact-form/ContactFormOverlay';\nimport CookieModal from './components/cookie-modal/CookieBanner';\nimport Footer from './components/footer/Footer';\nimport LoadingIndicator from './components/loading/Loading';\nimport { NavigationBar } from './components/navigation-bar/NavigationBar';\nimport ScrollToTop from './components/scroll-to-top/ScrollToTop';\nimport Sidebar from './components/sidebar/Sidebar';\nimport { htmlHead } from './configuration/html-heads';\nimport { useNotifications } from './hooks/notifications';\nimport routes from './routes';\nimport {\n forgotPasswordRequest,\n getCurrentAccount,\n isSessionExpired,\n msalPca,\n} from './services/auth';\nimport {\n autoLogin,\n loginSuccess,\n logoutSuccess,\n tokenAcquired,\n} from './store/actions/authActions';\nimport { setBasicAlert } from './store/actions/notificationsActions';\nimport {\n loadBatchOfUserNotifications,\n loadUnreadNotificationsCount,\n updateCurrentPageNumber,\n} from './store/actions/userNotificationsActions';\nimport {\n notificationsBasicAlertSelector,\n partnerCurrentPartner,\n} from './store/selectors';\nimport { isUserPreferenceCookieSet } from './util/cookies/cookies';\n\nconst Dashboard = lazy(() => import('./dynamic-pages/Dashboard'));\nconst ProductPage = lazy(() => import('./dynamic-pages/ProductPage'));\nconst Checkout = lazy(() => import('./dynamic-pages/Checkout'));\nconst NotFound = lazy(() => import('./pages/mp404'));\nconst Invitation = lazy(() => import('./dynamic-pages/Invitation'));\nconst ProductCatalog = lazy(() => import('./dynamic-pages/ProductCatalog'));\nconst Homepage = lazy(() => import('./pages/homepage'));\nconst Imprint = lazy(() => import('./pages/imprint'));\nconst DataPrivacy = lazy(() => import('./pages/data-privacy'));\n//const OurVision = lazy(() => import('./pages/our-vision')); // will be used again later\nconst TermsOfUse = lazy(() => import('./pages/terms-of-use'));\n\ninterface AppContentProps {\n handleAllCookies: () => void;\n handleSelectedCookies: () => void;\n}\n\nconst AppContent: React.FC = (props) => {\n const currentPartner = useSelector(partnerCurrentPartner);\n const alert = useSelector(notificationsBasicAlertSelector);\n const dispatch = useDispatch();\n const location = useLocation();\n useNotifications();\n const footerDisplayed = !location.pathname.includes(routes.dashboard.base);\n const [cookieFlag, setCookieFlag] = useState();\n\n useEffect(() => {\n if (currentPartner && currentPartner.id) {\n dispatch(updateCurrentPageNumber(0));\n dispatch(loadBatchOfUserNotifications(currentPartner.id, 0));\n dispatch(loadUnreadNotificationsCount(currentPartner.id));\n }\n }, [dispatch, currentPartner]);\n\n useEffect(() => {\n setCookieFlag(isUserPreferenceCookieSet());\n }, []);\n\n useEffect(() => {\n const eventListener = msalPca.addEventCallback((message: EventMessage) => {\n switch (message.eventType) {\n case EventType.LOGIN_SUCCESS: {\n dispatch(\n loginSuccess(\n (message.payload as AuthenticationResult)?.account as AccountInfo\n )\n );\n break;\n }\n case EventType.LOGIN_FAILURE: {\n // If login flow fails with forgot password error\n if (\n (message?.error as AuthError)?.errorMessage?.indexOf(\n 'AADB2C90118'\n ) > -1\n ) {\n // start the reset password flow\n msalPca\n .loginRedirect({\n ...forgotPasswordRequest,\n })\n .catch((err) => {\n console.log('error at loginRedirect: ', err);\n dispatch(\n setBasicAlert({\n messageKey: 'generalErrorMessage',\n severity: 'error',\n })\n );\n });\n }\n break;\n }\n case EventType.LOGOUT_SUCCESS: {\n dispatch(logoutSuccess());\n break;\n }\n case EventType.ACQUIRE_TOKEN_SUCCESS: {\n //when token is fetched\n dispatch(tokenAcquired());\n }\n }\n });\n\n // autologin on refresh\n // getCurrentAccount checks the cached id token for the account\n const currentAccount = getCurrentAccount();\n if (currentAccount) {\n isSessionExpired()\n .then((expired) => {\n if (!expired) {\n dispatch(autoLogin(currentAccount));\n if (currentPartner && currentPartner.id) {\n dispatch(updateCurrentPageNumber(0));\n dispatch(loadBatchOfUserNotifications(currentPartner.id, 0));\n dispatch(loadUnreadNotificationsCount(currentPartner.id));\n }\n }\n })\n .catch((error) => {\n console.log('token fetching failed, logging out:', error);\n console.log(location);\n //only logout locally, cookies on b2c server aren't cleared\n if (\n !location.pathname.includes(routes.dashboard.base) &&\n location.pathname !== routes.invitation\n ) {\n msalPca\n .logoutRedirect({\n onRedirectNavigate: () => {\n return false;\n },\n })\n .catch((e) => {\n console.log('error at logoutRedirect: ', e);\n dispatch(\n setBasicAlert({\n messageKey: 'generalErrorMessage',\n severity: 'error',\n })\n );\n });\n } else {\n msalPca.logoutRedirect().catch((e) => {\n console.log('error at logoutRedirect: ', e);\n dispatch(\n setBasicAlert({\n messageKey: 'generalErrorMessage',\n severity: 'error',\n })\n );\n });\n }\n });\n }\n\n return () => {\n if (eventListener) {\n msalPca.removeEventCallback(eventListener);\n }\n };\n // Do not add currentPartner as dependency since it will lead to infinite loop\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dispatch]);\n\n const routingComponent = (\n \n \n \n \n \n \n \n \n \n {/* // will be used again later*/}\n \n \n \n );\n\n const noSidebarDisplayed =\n location.pathname.includes('/checkout') ||\n location.pathname.includes(routes.dashboard.base);\n\n return (\n \n {htmlHead}\n \n \n \n \n {!noSidebarDisplayed && (\n \n \n \n )}\n \n }\n >\n \n \n {footerDisplayed && (\n \n )}\n {!cookieFlag && (\n {\n setCookieFlag(true);\n props.handleSelectedCookies();\n }}\n onAll={() => {\n setCookieFlag(true);\n props.handleAllCookies();\n }}\n />\n )}\n \n \n );\n};\n\nexport default AppContent;\n","import { AccountInfo } from '@azure/msal-browser';\nimport { AnyAction, Reducer } from 'redux';\nimport { User } from '../../models/user';\nimport { localService } from '../../services/localService';\nimport { AuthActionTypes } from '../actions/authActions';\n\nexport interface AuthState {\n user: User | null;\n tokenAcquired: boolean;\n}\n\nconst initialState: AuthState = {\n user: null,\n tokenAcquired: false,\n};\n\nexport const authReducer: Reducer = (\n state = initialState,\n action\n) => {\n switch (action.type) {\n case AuthActionTypes.AUTO_LOGIN:\n case AuthActionTypes.LOGIN_SUCCESS: {\n const account = action.payload as AccountInfo;\n const claims = account?.idTokenClaims as any;\n\n return {\n ...state,\n user: {\n id: account?.localAccountId as string,\n email: claims?.emails?.[0],\n firstName: claims?.given_name,\n lastName: claims?.family_name,\n fullName: `${claims?.given_name} ${claims?.family_name}`,\n },\n };\n }\n case AuthActionTypes.LOGOUT_SUCCESS: {\n localService.clearCurrentPartner();\n return {\n ...state,\n user: initialState.user,\n };\n }\n case AuthActionTypes.TOKEN_ACQUIRED: {\n return {\n ...state,\n tokenAcquired: true,\n };\n }\n default:\n return state;\n }\n};\n","import { mapKeys } from 'lodash';\nimport { Reducer } from 'redux';\nimport { GetPartnersProductsAllDtoOut } from '../../services/partners-products/dtos/get-partners-products-all/get-partners-products-all-dto-out';\nimport {\n DashboardProductsActions,\n DashboardProductsActionTypes,\n} from '../actions/dashboardProductsActions';\n\nexport interface DashboardProductsState {\n products: { [id: string]: GetPartnersProductsAllDtoOut };\n loading: boolean;\n error: any;\n}\n\nconst initialState: DashboardProductsState = {\n products: {},\n loading: false,\n error: null,\n};\n\nexport const dashboardProductsReducer: Reducer<\n DashboardProductsState,\n DashboardProductsActions\n> = (state = initialState, action): DashboardProductsState => {\n switch (action.type) {\n case DashboardProductsActionTypes.LOAD_ALL_DASHBOARD_PRODUCTS_SUCCESS: {\n return {\n ...state,\n products: mapKeys(action.payload, 'id'),\n loading: false,\n error: null,\n };\n }\n case DashboardProductsActionTypes.LOAD_ALL_DASHBOARD_PRODUCTS_FAIL: {\n return {\n ...state,\n error: action.payload,\n loading: false,\n };\n }\n case DashboardProductsActionTypes.SET_DASHBOARD_PRODUCTS_LOADING: {\n return {\n ...state,\n loading: action.payload,\n };\n }\n case DashboardProductsActionTypes.SET_PRODUCT_STATUS: {\n const product = state.products[action.payload.productId];\n if (product) {\n const products = { ...state.products };\n products[action.payload.productId] = {\n ...product,\n status: action.payload.status,\n };\n return {\n ...state,\n products,\n };\n }\n return state;\n }\n case DashboardProductsActionTypes.DELETE_DASHBOARD_PRODUCT_SUCCESS: {\n const newDashboardProducts = { ...state.products };\n delete newDashboardProducts[action.payload];\n\n return {\n ...state,\n products: newDashboardProducts,\n };\n }\n case DashboardProductsActionTypes.CLEAR_DASHBOARD_PRODUCTS: {\n return {\n ...state,\n products: {},\n loading: action.payload,\n };\n }\n default:\n return state;\n }\n};\n","import { mapKeys } from 'lodash';\nimport { Reducer } from 'redux';\nimport { GetPartnerProductStatisticsDtoOut } from '../../services/partner-statistics/dtos/get-partners-statistics-all-dto-out';\nimport {\n DashboardProductStatisticsActions,\n DashboardProductStatisticsActionTypes,\n} from '../actions/dashboardStatisticsActions';\n\nexport interface DashboardStatisticsState {\n statistics: { [id: string]: GetPartnerProductStatisticsDtoOut };\n loading: { [id: string]: boolean };\n error: any;\n}\n\nconst initialState: DashboardStatisticsState = {\n statistics: {},\n loading: {},\n error: null,\n};\n\nexport const dashboardStatisticsReducer: Reducer<\n DashboardStatisticsState,\n DashboardProductStatisticsActions\n> = (state = initialState, action): DashboardStatisticsState => {\n switch (action.type) {\n case DashboardProductStatisticsActionTypes.LOAD_PRODUCT_DASHBOARD_STATISTICS_SUCCESS: {\n const newStatistic = mapKeys([action.payload], 'id');\n return {\n ...state,\n statistics: { ...state.statistics, ...newStatistic },\n loading: { ...state.loading, [action.payload.id]: false },\n error: null,\n };\n }\n case DashboardProductStatisticsActionTypes.LOAD_PRODUCT_DASHBOARD_STATISTICS_FAIL: {\n return {\n ...state,\n error: action.payload.err,\n loading: { ...state.loading, [action.payload.id]: false },\n };\n }\n case DashboardProductStatisticsActionTypes.SET_DASHBOARD_PRODUCT_STATISTICS_LOADING: {\n return {\n ...state,\n loading: {\n ...state.loading,\n [action.payload.id]: action.payload.value,\n },\n };\n }\n default:\n return state;\n }\n};\n","import { Reducer } from 'redux';\nimport { SignalRMessageType } from '../../models/enums';\nimport {\n NotificationsActionTypes,\n NotificationsActions,\n} from '../actions/notificationsActions';\n\nexport interface BasicAlert {\n messageKey: string;\n severity: 'success' | 'info' | 'warning' | 'error' | undefined;\n}\n\nexport interface SignalRAlert extends BasicAlert {\n subscriptionId?: string;\n messageType?: SignalRMessageType;\n}\n\nexport interface NotificationsState {\n signalRAlert: SignalRAlert | null;\n basicAlert: BasicAlert | null;\n}\n\nconst initialNotificationsState: NotificationsState = {\n signalRAlert: null,\n basicAlert: null,\n};\n\nexport const notificationsReducer: Reducer<\n NotificationsState,\n NotificationsActions\n> = (state = initialNotificationsState, action) => {\n switch (action.type) {\n case NotificationsActionTypes.SET_SIGNALR_ALERT: {\n return {\n ...state,\n signalRAlert: action.alert,\n };\n }\n case NotificationsActionTypes.CLEAR_SIGNALR_ALERT: {\n return {\n ...state,\n signalRAlert: null,\n };\n }\n case NotificationsActionTypes.SET_BASIC_ALERT: {\n return {\n ...state,\n basicAlert: action.alert,\n };\n }\n case NotificationsActionTypes.CLEAR_BASIC_ALERT: {\n return {\n ...state,\n basicAlert: null,\n };\n }\n default:\n return state;\n }\n};\n","import { Reducer } from 'redux';\nimport { MemberStatus } from '../../models/enums';\nimport Partner, {\n PartnerApplication,\n PartnerMember,\n UserPartner,\n} from '../../models/partner';\nimport { SecurityLog } from '../../models/security-log';\nimport { PartnerActionTypes, PartnerActions } from '../actions/partnerActions';\n\nexport interface PartnerState {\n userPartners?: UserPartner[];\n currentPartner?: UserPartner;\n partner?: Partner;\n loadingPartner: boolean;\n loadingPartnerFormSubmission: boolean;\n loadingPartners: boolean;\n error?: string;\n securityLogs?: SecurityLog[];\n addMemberLoading: boolean;\n addMemberError: string;\n removeMemberEmail: string;\n removeMemberError: string;\n updateMemberRoleLoading: boolean;\n updateMemberRoleError: string;\n addApplicationLoading: boolean;\n addApplicationError: string;\n dashboardPartnerEditMode: boolean;\n dashboardPartnerCreateMode: boolean;\n inviteMemberLoading: boolean;\n invitationStatus?: MemberStatus;\n}\n\nconst initialState: PartnerState = {\n userPartners: undefined,\n currentPartner: undefined,\n partner: undefined,\n loadingPartner: true,\n loadingPartnerFormSubmission: false,\n loadingPartners: false,\n error: undefined,\n securityLogs: undefined,\n addMemberLoading: false,\n addMemberError: '',\n removeMemberEmail: '',\n removeMemberError: '',\n updateMemberRoleLoading: false,\n updateMemberRoleError: '',\n addApplicationLoading: false,\n addApplicationError: '',\n dashboardPartnerEditMode: false,\n dashboardPartnerCreateMode: false,\n inviteMemberLoading: false,\n invitationStatus: undefined,\n};\n\nexport const partnerReducer: Reducer = (\n state = initialState,\n action\n) => {\n switch (action.type) {\n case PartnerActionTypes.SET_PARTNER_LOADING: {\n return {\n ...state,\n loadingPartner: action.payload as boolean,\n };\n }\n case PartnerActionTypes.SET_PARTNER_FORM_SUBMISSION_LOADING: {\n return {\n ...state,\n loadingPartnerFormSubmission: action.payload as boolean,\n };\n }\n case PartnerActionTypes.SET_PARTNERS_LOADING: {\n return {\n ...state,\n loadingPartners: action.payload as boolean,\n };\n }\n case PartnerActionTypes.SET_PARTNER_ERROR: {\n return {\n ...state,\n loadingPartner: false,\n loadingPartnerFormSubmission: false,\n loadingPartners: false,\n error: action.payload as string,\n };\n }\n case PartnerActionTypes.LOAD_PARTNER_SUCCESS: {\n return {\n ...state,\n partner: action.payload as Partner,\n error: undefined,\n loadingPartner: false,\n };\n }\n case PartnerActionTypes.ADD_MEMBER_LOADING: {\n return {\n ...state,\n addMemberLoading: action.payload as boolean,\n };\n }\n case PartnerActionTypes.ADD_MEMBER_ERROR: {\n return {\n ...state,\n addMemberLoading: false,\n addMemberError: action.payload as string,\n };\n }\n case PartnerActionTypes.ADD_MEMBER_SUCCESS: {\n let newMembers: PartnerMember[];\n state.partner && state.partner.members\n ? (newMembers = state.partner.members)\n : (newMembers = []);\n newMembers.push(action.payload as PartnerMember);\n if (state.partner) {\n return {\n ...state,\n addMemberLoading: false,\n partner: { ...state.partner, members: newMembers },\n };\n } else {\n return state;\n }\n }\n case PartnerActionTypes.ADD_APPLICATION_LOADING: {\n return {\n ...state,\n addApplicationLoading: action.payload as boolean,\n };\n }\n case PartnerActionTypes.ADD_APPLICATION_ERROR: {\n return {\n ...state,\n addApplicationLoading: false,\n addApplicationError: action.payload as string,\n };\n }\n case PartnerActionTypes.ADD_APPLICATION_SUCCESS: {\n let newApplications: PartnerApplication[];\n state.partner && state.partner.applications\n ? (newApplications = state.partner.applications)\n : (newApplications = []);\n newApplications.push(action.payload as PartnerApplication);\n if (state.partner) {\n return {\n ...state,\n addApplicationLoading: false,\n partner: { ...state.partner, applications: newApplications },\n };\n } else {\n return state;\n }\n }\n case PartnerActionTypes.REMOVE_MEMBER_LOADING: {\n return {\n ...state,\n removeMemberEmail: action.payload as string,\n };\n }\n case PartnerActionTypes.REMOVE_MEMBER_ERROR: {\n return {\n ...state,\n removeMemberEmail: '',\n removeMemberError: action.payload as string,\n };\n }\n case PartnerActionTypes.REMOVE_MEMBER_SUCCESS: {\n let newMembers: PartnerMember[];\n state.partner && state.partner.members\n ? (newMembers = state.partner.members)\n : (newMembers = []);\n const removedMember = action.payload as {\n userId: string;\n email: string;\n };\n\n if (removedMember.userId)\n newMembers = newMembers.filter(\n (member) => member.user.email !== removedMember.userId\n );\n else\n newMembers = newMembers.filter(\n (member) => member.user.email !== removedMember.email\n );\n\n if (state.partner) {\n return {\n ...state,\n removeMemberEmail: '',\n partner: { ...state.partner, members: newMembers },\n };\n } else {\n return state;\n }\n }\n case PartnerActionTypes.UPDATE_MEMBER_ROLE_LOADING: {\n return {\n ...state,\n updateMemberRoleLoading: action.payload as boolean,\n };\n }\n case PartnerActionTypes.UPDATE_MEMBER_ROLE_ERROR: {\n return {\n ...state,\n updateMemberRoleLoading: false,\n updateMemberRoleError: action.payload as string,\n };\n }\n case PartnerActionTypes.UPDATE_MEMBER_ROLE_SUCCESS: {\n let newMembers: PartnerMember[];\n state.partner && state.partner.members\n ? (newMembers = state.partner.members)\n : (newMembers = []);\n newMembers[\n newMembers.findIndex(\n (member) =>\n member.user.id === (action.payload as PartnerMember).user.id\n )\n ] = action.payload as PartnerMember;\n if (state.partner) {\n return {\n ...state,\n removeMemberEmail: '',\n partner: { ...state.partner, members: newMembers },\n };\n } else {\n return state;\n }\n }\n case PartnerActionTypes.LOAD_PARTNERS_OF_USER_SUCCESS: {\n return {\n ...state,\n userPartners: action.payload as UserPartner[],\n loadingPartners: false,\n };\n }\n case PartnerActionTypes.SET_CURRENT_PARTNER: {\n return {\n ...state,\n currentPartner: action.payload as UserPartner,\n };\n }\n case PartnerActionTypes.SET_DASHBOARD_PARTNER_CREATE: {\n return {\n ...state,\n dashboardPartnerCreateMode: action.payload as boolean,\n };\n }\n case PartnerActionTypes.SET_PARTNER_SECURITY_LOGS: {\n return {\n ...state,\n securityLogs: action.payload as SecurityLog[],\n };\n }\n case PartnerActionTypes.SET_INVITATION_LOADING: {\n return {\n ...state,\n inviteMemberLoading: action.payload as boolean,\n };\n }\n case PartnerActionTypes.SET_INVITATION_STATUS: {\n return {\n ...state,\n invitationStatus: action.payload as MemberStatus,\n };\n }\n default:\n return state;\n }\n};\n","import { Reducer } from 'redux';\nimport {\n PaymentMethodsActionTypes,\n PaymentMethodsActions,\n} from '../actions/paymentMethodsActions';\nimport { SepaBankAccount } from '../../models/sepaBankAccount';\nimport { mapKeys, omit } from 'lodash';\nimport { PaymentMethods } from '../../services/payment-methods/payment-methods-service';\nimport { CreditCard } from '../../models/creditCard';\nimport { PaymentMethodId } from '../../models/enums';\n\nexport interface PaymentMethodsState {\n cards: { [cardId: string]: CreditCard };\n bankAccounts: { [accountId: string]: SepaBankAccount };\n selectedPaymentMethod: string;\n loading: boolean;\n}\n\nconst initialPaymentMethodsState: PaymentMethodsState = {\n cards: {},\n bankAccounts: {},\n selectedPaymentMethod: PaymentMethodId.INVOICE_PAYMENT_ID,\n loading: true,\n};\n\nexport const paymentMethodsReducer: Reducer<\n PaymentMethodsState,\n PaymentMethodsActions\n> = (state = initialPaymentMethodsState, action) => {\n switch (action.type) {\n case PaymentMethodsActionTypes.LOAD_ALL_SUCCESS: {\n return {\n ...state,\n loading: false,\n cards: mapKeys((action.payload as PaymentMethods).cards, 'id'),\n bankAccounts: mapKeys(\n (action.payload as PaymentMethods).bankAccounts,\n 'id'\n ),\n };\n }\n case PaymentMethodsActionTypes.DELETE_SUCCESS: {\n const deletedPaymentMethodId = action.payload as unknown as string;\n\n return {\n ...state,\n loading: false,\n cards: omit(state.cards, deletedPaymentMethodId),\n bankAccounts: omit(state.bankAccounts, deletedPaymentMethodId),\n };\n }\n case PaymentMethodsActionTypes.SET_LOADING: {\n return {\n ...state,\n loading: action.payload as unknown as boolean,\n };\n }\n case PaymentMethodsActionTypes.SET_SELECTED_PAYMENT_METHOD: {\n return {\n ...state,\n selectedPaymentMethod: action.payload as unknown as string,\n };\n }\n default:\n return state;\n }\n};\n","import { cloneDeep } from 'lodash';\nimport { Reducer } from 'redux';\nimport { ProductApiSpecification } from '../../models/productApiSpecification';\nimport {\n ProductsApiSpecificationActions,\n ProductsApiSpecificationActionTypes,\n} from '../actions/productsApiSpecificationActions';\n\nexport interface ProductsApiSpecificationState {\n productsApiSpecification: { [productId: string]: ProductApiSpecification | string };\n loading: boolean;\n}\n\nconst initialProductsApiSpecificationState: ProductsApiSpecificationState = {\n productsApiSpecification: {},\n loading: false,\n};\n\nexport const productsApiSpecificationReducer: Reducer<\n ProductsApiSpecificationState,\n ProductsApiSpecificationActions\n> = (state = initialProductsApiSpecificationState, action) => {\n switch (action.type) {\n case ProductsApiSpecificationActionTypes.LOAD_PRODUCT_API_SPECIFICATION_BY_PRODUCT_ID_SUCCESS: {\n return {\n ...state,\n productsApiSpecification: cloneDeep({\n ...state.productsApiSpecification,\n [action.payload.productId]: action.payload.data,\n }),\n loading: false,\n };\n }\n case ProductsApiSpecificationActionTypes.SET_LOADING: {\n return {\n ...state,\n loading: (action.payload as unknown) as boolean,\n };\n }\n default:\n return state;\n }\n};\n","import { mapKeys } from 'lodash';\nimport { Reducer } from 'redux';\nimport { Category } from '../../models/enums';\nimport { Product } from '../../models/product';\nimport {\n ProductsActions,\n ProductsActionTypes,\n} from '../actions/productsActions';\n\nexport interface ProductsState {\n product?: Product;\n products: { [id: string]: Product };\n loading: boolean;\n loadProductErrorMessage: string | undefined;\n selectedProductCategory: Category;\n}\n\nconst initialState: ProductsState = {\n product: undefined,\n products: {},\n loading: false,\n loadProductErrorMessage: undefined,\n selectedProductCategory: Category.ALL_PRODUCTS,\n};\n\nexport const productsReducer: Reducer = (\n state = initialState,\n action\n) => {\n switch (action.type) {\n case ProductsActionTypes.CREATE_PRODUCT_SUCCESS: {\n const newProduct = action.data as unknown as Product;\n state.products[newProduct.id] = newProduct;\n return {\n ...state,\n };\n }\n case ProductsActionTypes.UPDATE_PRODUCT_SUCCESS: {\n const updatedProduct = action.data as unknown as Product;\n state.products[updatedProduct.id] = updatedProduct;\n return {\n ...state,\n };\n }\n case ProductsActionTypes.LOAD_ALL_SUCCESS: {\n return {\n ...state,\n products: mapKeys(action.data, 'id'),\n loading: false,\n };\n }\n case ProductsActionTypes.LOAD_BY_ID_SUCCESS: {\n return {\n ...state,\n product: action.data,\n loading: false,\n loadProductErrorMessage: undefined,\n };\n }\n case ProductsActionTypes.LOAD_BY_ID_FAIL: {\n return {\n ...state,\n loading: false,\n loadProductErrorMessage: action.data,\n };\n }\n case ProductsActionTypes.SET_LOADING: {\n return {\n ...state,\n loading: action.payload as unknown as boolean,\n };\n }\n default:\n return state;\n }\n};\n","import { groupBy, map, mapKeys } from 'lodash';\nimport { Reducer } from 'redux';\nimport {\n ProductCoreCost,\n SubscriptionCoreCost,\n} from '../../models/subscriptionCosts';\nimport { findFirstUnitLabel } from '../../util/util';\nimport {\n SubscriptionsCostsActions,\n SubscriptionsCostsActionTypes,\n} from '../actions/subscriptionsCostsActions';\n\nexport interface SubscriptionsCostsState {\n costsBySubscriptions: { [subscriptionId: string]: SubscriptionCoreCost };\n costsByProducts: { [productId: string]: ProductCoreCost };\n loading: boolean;\n error: any;\n}\n\nconst initialState: SubscriptionsCostsState = {\n costsBySubscriptions: {},\n costsByProducts: {},\n loading: false,\n error: null,\n};\n\nconst bySubscriptionToByProduct = ({\n subscription,\n ...byProduct\n}: SubscriptionCoreCost): ProductCoreCost => {\n return {\n ...byProduct,\n productId: subscription.productId,\n productName: subscription.productName,\n unitLabel: findFirstUnitLabel(subscription.plan),\n };\n};\n\nconst groupCostByProduct = (\n subscriptionCost: SubscriptionCoreCost[]\n): { [productId: string]: ProductCoreCost } =>\n mapKeys(\n map(groupBy(subscriptionCost, 'subscription.productId'), (c) =>\n c.reduce((c1, c2) => ({\n ...c1,\n currentCost: c1.currentCost + c2.currentCost,\n currentUsage: c1.currentUsage + c2.currentUsage,\n }))\n ).map(bySubscriptionToByProduct),\n 'productId'\n );\n\nexport const subscriptionsCostsReducer: Reducer<\n SubscriptionsCostsState,\n SubscriptionsCostsActions\n> = (state = initialState, action): SubscriptionsCostsState => {\n switch (action.type) {\n case SubscriptionsCostsActionTypes.LOAD_COSTS_SUCCESS: {\n return {\n ...state,\n costsBySubscriptions: mapKeys(action.payload, 'subscription.id'),\n costsByProducts: groupCostByProduct(action.payload),\n loading: false,\n error: null,\n };\n }\n case SubscriptionsCostsActionTypes.LOAD_COSTS_FAIL: {\n return {\n ...state,\n error: action.payload,\n loading: false,\n };\n }\n case SubscriptionsCostsActionTypes.SET_COSTS_LOADING: {\n return {\n ...state,\n loading: action.payload,\n };\n }\n default:\n return state;\n }\n};\n","import { mapKeys, mapValues } from 'lodash';\nimport { Reducer } from 'redux';\nimport { Subscription } from '../../models/subscription';\nimport {\n SubscriptionsActions,\n SubscriptionsActionTypes,\n} from '../actions/subscriptionsActions';\n\nexport interface SubscriptionsState {\n subscriptions: { [id: string]: Subscription };\n subscriptionDetailsStatus: {\n [id: string]: {\n loadingPrimaryKey: boolean;\n loadingSecondaryKey: boolean;\n subscriptionKeyLoadError: boolean;\n }\n }\n subscriptionsLoading: boolean; \n loadingCreateSubscription: boolean;\n subscriptionCreateErrorMessage: string | undefined;\n}\n\nconst initialSubscriptionsState: SubscriptionsState = {\n subscriptions: {},\n subscriptionDetailsStatus: {},\n subscriptionsLoading: false,\n loadingCreateSubscription: false,\n subscriptionCreateErrorMessage: undefined,\n};\n\nexport const subscriptionsReducer: Reducer<\n SubscriptionsState,\n SubscriptionsActions\n> = (state = initialSubscriptionsState, action) => {\n switch (action.type) {\n case SubscriptionsActionTypes.CREATE_SUBSCRIPTION_SUCCESS: {\n const newSubscription = action.payload;\n state.subscriptions[newSubscription.id] = newSubscription;\n state.subscriptionDetailsStatus[newSubscription.id] = {\n loadingPrimaryKey: false,\n loadingSecondaryKey: false,\n subscriptionKeyLoadError: false\n };\n return {\n ...state,\n subscriptionCreateErrorMessage: undefined,\n loadingCreateSubscription: false,\n };\n }\n case SubscriptionsActionTypes.CREATE_SUBSCRIPTION_FAIL: {\n return {\n ...state,\n subscriptionCreateErrorMessage: action.payload,\n };\n }\n case SubscriptionsActionTypes.LOAD_BY_PARTNERID_SUCCESS: {\n const subscriptions = mapKeys(\n action.payload,\n 'id'\n );\n return {\n ...state,\n subscriptions: subscriptions,\n subscriptionDetailsStatus: mapValues(subscriptions, () => ({\n loadingPrimaryKey: false,\n loadingSecondaryKey: false,\n subscriptionKeyLoadError: false\n })),\n subscriptionsLoading: false\n };\n }\n case SubscriptionsActionTypes.SET_SUBSCRIPTIONS_LOADING: {\n return {\n ...state,\n subscriptionsLoading: action.payload,\n };\n }\n case SubscriptionsActionTypes.SET_LOADING_SUBSCRIPTION_CREATE: {\n return {\n ...state,\n loadingCreateSubscription: action.payload,\n };\n }\n case SubscriptionsActionTypes.SET_PRIMARY_KEY_LOADING: {\n const subscriptionStatus = action.payload;\n return {\n ...state,\n subscriptionDetailsStatus: {\n ...state.subscriptionDetailsStatus,\n [subscriptionStatus.subscriptionId]: {\n ...state.subscriptionDetailsStatus[subscriptionStatus.subscriptionId],\n loadingPrimaryKey: subscriptionStatus.loading\n },\n }\n };\n }\n case SubscriptionsActionTypes.SET_SECONDARY_KEY_LOADING: {\n const subscriptionStatus = action.payload;\n return {\n ...state,\n subscriptionDetailsStatus: {\n ...state.subscriptionDetailsStatus,\n [subscriptionStatus.subscriptionId]: {\n ...state.subscriptionDetailsStatus[subscriptionStatus.subscriptionId],\n loadingSecondaryKey: subscriptionStatus.loading\n },\n }\n };\n }\n case SubscriptionsActionTypes.SET_PRIMARY_KEY: {\n const renewResult = action.payload;\n return {\n ...state,\n subscriptions: {\n ...state.subscriptions,\n [renewResult.id]: {\n ...state.subscriptions[renewResult.id],\n primaryKey: renewResult.primaryKey,\n },\n }\n };\n }\n case SubscriptionsActionTypes.SET_SECONDARY_KEY: {\n const renewResult = action.payload;\n return {\n ...state,\n subscriptions: {\n ...state.subscriptions,\n [renewResult.id]: {\n ...state.subscriptions[renewResult.id],\n secondaryKey: renewResult.secondaryKey,\n },\n }\n };\n }\n case SubscriptionsActionTypes.SET_SUBSCRIPTION: {\n const subscription = action.payload;\n return {\n ...state,\n subscriptions: {\n ...state.subscriptions,\n [subscription.id]: subscription,\n },\n };\n }\n case SubscriptionsActionTypes.GET_SUBSCRIPTION_KEYS_SUCCESS: {\n const response = action.payload;\n return {\n ...state,\n subscriptions: {\n ...state.subscriptions,\n [response.id]: {\n ...state.subscriptions[response.id],\n primaryKey: response.primaryKey,\n secondaryKey: response.secondaryKey\n },\n }\n };\n }\n case SubscriptionsActionTypes.GET_SUBSCRIPTION_KEYS_ERROR: {\n const response = action.payload;\n return {\n ...state,\n subscriptionDetailsStatus: {\n ...state.subscriptionDetailsStatus,\n [response.subscriptionId]: {\n ...state.subscriptionDetailsStatus[response.subscriptionId],\n subscriptionKeyLoadError: response.isError\n },\n }\n };\n }\n default:\n return state;\n }\n};\n","import { groupBy, map, mapKeys, mean } from 'lodash';\nimport { Reducer } from 'redux';\nimport {\n ProductCoreUsage,\n SubscriptionCoreUsage,\n} from '../../models/subscriptionUsages';\nimport {\n SubscriptionsUsagesActions,\n SubscriptionsUsagesActionTypes,\n} from '../actions/subscriptionsUsagesActions';\n\nexport interface SubscriptionsUsagesState {\n usagesBySubscriptions: { [subscriptionId: string]: SubscriptionCoreUsage };\n usagesByProducts: { [productId: string]: ProductCoreUsage };\n loading: boolean;\n error: any;\n}\n\nconst initialState: SubscriptionsUsagesState = {\n usagesBySubscriptions: {},\n usagesByProducts: {},\n loading: false,\n error: null,\n};\n\nconst bySubscriptionToByProduct = ({\n subscriptionId,\n note,\n ...byProduct\n}: SubscriptionCoreUsage) => byProduct;\n\nconst groupUsageByProduct = (subscriptionUsage: SubscriptionCoreUsage[]) =>\n mapKeys(\n map(groupBy(subscriptionUsage, 'productId'), (c) =>\n c.reduce((u1, u2) => ({\n ...u1,\n unitLabel: u1.unitLabel || u2.unitLabel,\n quantity: u1.quantity + u2.quantity,\n callCountTotal: u1.callCountTotal + u2.callCountTotal,\n errorRate: mean([u1.errorRate, u2.errorRate]),\n latencyAvg: mean([u1.latencyAvg, u2.latencyAvg]),\n }))\n ).map(bySubscriptionToByProduct),\n 'productId'\n );\n\nexport const subscriptionsUsagesReducer: Reducer<\n SubscriptionsUsagesState,\n SubscriptionsUsagesActions\n> = (state = initialState, action): SubscriptionsUsagesState => {\n switch (action.type) {\n case SubscriptionsUsagesActionTypes.LOAD_USAGE_SUCCESS: {\n return {\n ...state,\n usagesBySubscriptions: mapKeys(action.payload, 'subscriptionId'),\n usagesByProducts: groupUsageByProduct(action.payload),\n loading: false,\n error: null,\n };\n }\n case SubscriptionsUsagesActionTypes.LOAD_USAGE_FAIL: {\n return {\n ...state,\n error: action.payload,\n loading: false,\n };\n }\n case SubscriptionsUsagesActionTypes.SET_USAGE_LOADING: {\n return {\n ...state,\n loading: action.payload,\n };\n }\n default:\n return state;\n }\n};\n","import { mapKeys } from 'lodash';\nimport { Reducer } from 'redux';\nimport { NotificationReadStatus } from '../../models/enums';\nimport { NotificationDataType } from '../../models/userNotification';\nimport {\n UserNotificationsActions,\n UserNotificationsActionTypes,\n} from '../actions/userNotificationsActions';\n\nexport interface UserNotificationState {\n notifications: { [id: string]: NotificationDataType };\n numberOfUnreadNotifications: number;\n currentPage: number;\n hasMorePages: boolean;\n numberOfNotificationsInLastBatch: number;\n}\n\nconst initialState: UserNotificationState = {\n notifications: {},\n numberOfUnreadNotifications: 0,\n currentPage: 0,\n hasMorePages: true,\n numberOfNotificationsInLastBatch: 0,\n};\n\nexport const userNoticationsReducer: Reducer<\n UserNotificationState,\n UserNotificationsActions\n> = (state = initialState, action) => {\n switch (action.type) {\n case UserNotificationsActionTypes.LOAD_FIRST_BATCH_OF_NOTIFICATIONS_SUCCESS: {\n const newNotifications = mapKeys(action.data, 'id');\n return {\n ...state,\n notifications: newNotifications,\n currentPage: state.currentPage + 1,\n numberOfNotificationsInLastBatch: action.data.length,\n hasMorePages: true,\n };\n }\n case UserNotificationsActionTypes.LOAD_BATCH_OF_NOTIFICATIONS_SUCCESS: {\n const newNotifications = mapKeys(action.data, 'id');\n return {\n ...state,\n notifications: { ...state.notifications, ...newNotifications },\n currentPage: state.currentPage + 1,\n numberOfNotificationsInLastBatch: action.data.length,\n };\n }\n case UserNotificationsActionTypes.NOTIFICATION_RECEIVED: {\n const newNotification = (action.data as unknown) as NotificationDataType;\n return {\n ...state,\n notifications: {\n ...state.notifications,\n [newNotification.id]: newNotification,\n },\n numberOfUnreadNotifications: state.numberOfUnreadNotifications + 1,\n };\n }\n case UserNotificationsActionTypes.GET_UNREAD_NOTIFICATIONS_COUNT_SUCCESS: {\n return {\n ...state,\n numberOfUnreadNotifications: action.data,\n };\n }\n case UserNotificationsActionTypes.UPDATE_HAS_MORE_PAGES: {\n return {\n ...state,\n hasMorePages: (action.data as unknown) as boolean,\n };\n }\n case UserNotificationsActionTypes.UPDATE_CURRENT_PAGE_NUMBER: {\n return {\n ...state,\n currentPage: action.data,\n };\n }\n case UserNotificationsActionTypes.READ_ALL_NOTIFICATIONS_SUCCESS: {\n const notifications = state.notifications;\n for (const key of Object.keys(notifications)) {\n notifications[key].readStatus = NotificationReadStatus.READ;\n }\n\n return {\n ...state,\n numberOfUnreadNotifications: 0,\n currentPage: 0,\n notifications: notifications,\n };\n }\n case UserNotificationsActionTypes.REMOVE_NOTIFICATION_BY_ID: {\n const notifications = {\n ...state.notifications,\n };\n delete notifications[action.data];\n\n return {\n ...state,\n notifications: notifications,\n };\n }\n default:\n return state;\n }\n};\n","import {\n connectRouter,\n routerMiddleware,\n RouterState,\n} from 'connected-react-router';\nimport { createBrowserHistory, History } from 'history';\nimport { isEmpty } from 'lodash';\nimport {\n applyMiddleware,\n combineReducers,\n compose,\n createStore,\n Store,\n} from 'redux';\nimport thunk from 'redux-thunk';\nimport { authReducer, AuthState } from './reducers/authReducer';\nimport {\n DashboardProductsState,\n dashboardProductsReducer,\n} from './reducers/dashboardProductsReducer';\nimport {\n dashboardStatisticsReducer,\n DashboardStatisticsState,\n} from './reducers/dashboardStatisticsReducer';\nimport {\n notificationsReducer,\n NotificationsState,\n} from './reducers/notificationsReducer';\nimport { partnerReducer, PartnerState } from './reducers/partnerReducer';\nimport {\n paymentMethodsReducer,\n PaymentMethodsState,\n} from './reducers/paymentMethodsReducer';\nimport {\n productsApiSpecificationReducer,\n ProductsApiSpecificationState,\n} from './reducers/productsApiSpecificationReducer';\nimport { productsReducer, ProductsState } from './reducers/productsReducer';\nimport {\n subscriptionsCostsReducer,\n SubscriptionsCostsState,\n} from './reducers/subscriptionsCostsReducer';\nimport {\n subscriptionsReducer,\n SubscriptionsState,\n} from './reducers/subscriptionsReducer';\nimport {\n subscriptionsUsagesReducer,\n SubscriptionsUsagesState,\n} from './reducers/subscriptionsUsagesReducer';\nimport {\n UserNotificationState,\n userNoticationsReducer,\n} from './reducers/userNotificationsReducer';\n\nexport interface AppState {\n router: RouterState;\n auth: AuthState;\n products: ProductsState;\n dashboardProducts: DashboardProductsState;\n dashboardStatistics: DashboardStatisticsState;\n paymentMethods: PaymentMethodsState;\n subscriptions: SubscriptionsState;\n partner: PartnerState;\n subscriptionsUsages: SubscriptionsUsagesState;\n subscriptionsCosts: SubscriptionsCostsState;\n productsApiSpecification: ProductsApiSpecificationState;\n notifications: NotificationsState;\n userNotifications: UserNotificationState;\n}\n\nconst publicUrl = process.env.PUBLIC_URL || '';\nexport const history = createBrowserHistory({ basename: publicUrl });\n\nconst createRootReducer = (history: History) =>\n combineReducers({\n router: !isEmpty(history) ? connectRouter(history) : ({} as any),\n auth: authReducer,\n products: productsReducer,\n dashboardProducts: dashboardProductsReducer,\n dashboardStatistics: dashboardStatisticsReducer,\n paymentMethods: paymentMethodsReducer,\n subscriptions: subscriptionsReducer,\n partner: partnerReducer,\n subscriptionsUsages: subscriptionsUsagesReducer,\n subscriptionsCosts: subscriptionsCostsReducer,\n productsApiSpecification: productsApiSpecificationReducer,\n notifications: notificationsReducer,\n userNotifications: userNoticationsReducer,\n });\n\nconst configureStore = (initialState?: AppState): Store => {\n const composeEnhancer: typeof compose =\n (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;\n\n const store = createStore(\n createRootReducer(history),\n initialState as any,\n !isEmpty(history)\n ? composeEnhancer(applyMiddleware(thunk, routerMiddleware(history)))\n : composeEnhancer(applyMiddleware(thunk))\n );\n return store;\n};\n\nexport const store = configureStore();\n","import React, { Suspense, useState } from 'react';\nimport { MsalProvider } from '@azure/msal-react';\nimport {\n ReactPlugin,\n withAITracking,\n} from '@microsoft/applicationinsights-react-js';\nimport { ApplicationInsights } from '@microsoft/applicationinsights-web';\nimport {\n Box,\n CssBaseline,\n StyledEngineProvider,\n ThemeProvider,\n} from '@mui/material';\nimport { ConnectedRouter } from 'connected-react-router';\nimport { Provider } from 'react-redux';\nimport './App.css';\nimport AppContent from './AppContent';\nimport { theme } from './AppTheme';\nimport LoadingIndicator from './components/loading/Loading';\nimport { appConfiguration } from './configuration';\nimport {\n COOKIE_ACCEPT_ALL,\n COOKIE_ONLY_NECESSARY,\n} from './constants/constants';\nimport { msalPca } from './services/auth';\nimport { history, store } from './store';\nimport {\n isCookieUseDisabledByUser,\n setUserPreferenceCookie,\n} from './util/cookies/cookies';\nimport { CookieContext } from './util/global-context';\n\nconst reactPlugin = new ReactPlugin();\nconst appInsights = reactPlugin\n ? new ApplicationInsights({\n config: {\n instrumentationKey: appConfiguration()?.appInsightsInstrumentationKey,\n extensions: [reactPlugin],\n extensionConfig: {\n [reactPlugin.identifier]: { history: history },\n },\n isCookieUseDisabled: isCookieUseDisabledByUser(),\n enableAutoRouteTracking: true,\n },\n })\n : undefined;\nappInsights?.loadAppInsights();\n\nconst App: React.FC = () => {\n const [statisticCookie, setStatisticCookieContext] = useState(false);\n\n const handleSelectedCookies = () => {\n if (statisticCookie) {\n handleAllCookies();\n } else {\n appInsights?.getCookieMgr().setEnabled(false);\n setUserPreferenceCookie(COOKIE_ONLY_NECESSARY);\n }\n };\n\n const handleAllCookies = () => {\n appInsights?.getCookieMgr().setEnabled(true);\n setUserPreferenceCookie(COOKIE_ACCEPT_ALL);\n };\n\n return (\n \n \n \n \n \n \n \n \n \n \n }\n >\n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default reactPlugin ? withAITracking(reactPlugin, App) : App;\n","import React from 'react';\nimport { render } from 'react-dom';\nimport App from './App';\n\nrender(\n \n \n ,\n document.getElementById('root')\n);\n","declare global {\n interface Window {\n MPConfig: AppConfiguration;\n }\n}\n\ninterface AppConfiguration {\n coreApiUrl: string;\n billingApiUrl: string;\n apimApiUrl: string;\n stripePublicKey: string;\n picturesCdnUrl: string;\n filesCdnUrl: string;\n friendlyCaptchaSiteKey: string;\n appInsightsInstrumentationKey: string;\n auth: {\n tenantName: string;\n clientId: string;\n };\n flags: {\n serviceCreationAndEditing: boolean;\n };\n env: string;\n local: {\n localePath: string;\n picturePath: string;\n };\n theme: string;\n htmlHeader: string;\n}\n\nexport const appConfiguration = () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n return window.MPConfig;\n};\n","import { ActionCreator, Dispatch } from 'redux';\nimport { ThunkAction } from 'redux-thunk';\nimport { AppState } from '..';\nimport { MemberStatus } from '../../models/enums';\nimport Partner, {\n NewPartnerMember,\n PartnerApplication,\n PartnerMember,\n UserPartner,\n} from '../../models/partner';\nimport { SecurityLog } from '../../models/security-log';\nimport { localService } from '../../services/localService';\nimport { partnerService } from '../../services/partners/partner-service';\nimport { setBasicAlert } from './notificationsActions';\n\nexport enum PartnerActionTypes {\n LOAD_PARTNERS_OF_USER_SUCCESS = 'user partners loaded',\n LOAD_PARTNER_SUCCESS = 'partner loaded',\n SET_PARTNER_LOADING = 'partner is loading',\n SET_PARTNER_FORM_SUBMISSION_LOADING = 'partner form is submitting',\n SET_PARTNERS_LOADING = 'partners are loading',\n SET_PARTNER_ERROR = 'error occurred in partner state',\n ADD_MEMBER_SUCCESS = 'add member success',\n ADD_MEMBER_LOADING = 'add member is loading',\n ADD_MEMBER_ERROR = 'add member error',\n REMOVE_MEMBER_SUCCESS = 'remove member success',\n REMOVE_MEMBER_LOADING = 'remove member is loading',\n REMOVE_MEMBER_ERROR = 'remove member error',\n UPDATE_MEMBER_ROLE_SUCCESS = 'update member role success',\n UPDATE_MEMBER_ROLE_LOADING = 'update member role is loading',\n UPDATE_MEMBER_ROLE_ERROR = 'update member role error',\n ADD_APPLICATION_SUCCESS = 'add application success',\n ADD_APPLICATION_LOADING = 'add application is loading',\n ADD_APPLICATION_ERROR = 'add application error',\n SET_CURRENT_PARTNER = 'set current partner',\n SET_DASHBOARD_PARTNER_EDIT = 'set dashboard partner edit state',\n SET_DASHBOARD_PARTNER_CREATE = 'set dashboard partner create state',\n SET_PARTNER_SECURITY_LOGS = 'set partner security logs',\n SET_INVITATION_STATUS = 'set invitation status',\n SET_INVITATION_LOADING = 'invitation status loading',\n}\n\ninterface LoadUserPartnersAction {\n type: PartnerActionTypes;\n payload: UserPartner[];\n}\n\nexport const setUserPartners = (\n partners: UserPartner[]\n): LoadUserPartnersAction => ({\n type: PartnerActionTypes.LOAD_PARTNERS_OF_USER_SUCCESS,\n payload: partners,\n});\n\ninterface LoadPartnerAction {\n type: PartnerActionTypes;\n payload?: Partner;\n}\n\nexport const setPartner = (partner?: Partner): LoadPartnerAction => ({\n type: PartnerActionTypes.LOAD_PARTNER_SUCCESS,\n payload: partner,\n});\n\ninterface SetLoadingPartnerAction {\n type: PartnerActionTypes;\n payload: boolean;\n}\n\nconst setPartnerLoading = (loading: boolean): SetLoadingPartnerAction => ({\n type: PartnerActionTypes.SET_PARTNER_LOADING,\n payload: loading,\n});\n\ninterface SetLoadingPartnerFormSubmissionAction {\n type: PartnerActionTypes;\n payload: boolean;\n}\n\nexport const setPartnerFormSubmissionLoading = (\n loading: boolean\n): SetLoadingPartnerFormSubmissionAction => ({\n type: PartnerActionTypes.SET_PARTNER_FORM_SUBMISSION_LOADING,\n payload: loading,\n});\n\ninterface SetLoadingPartnersAction {\n type: PartnerActionTypes;\n payload: boolean;\n}\n\nconst setPartnersLoading = (loading: boolean): SetLoadingPartnersAction => ({\n type: PartnerActionTypes.SET_PARTNERS_LOADING,\n payload: loading,\n});\n\ninterface SetPartnerSecurityLogsAction {\n type: PartnerActionTypes;\n payload: SecurityLog[];\n}\n\nconst setPartnerSecurityLogs = (\n securityLogs: SecurityLog[]\n): SetPartnerSecurityLogsAction => ({\n type: PartnerActionTypes.SET_PARTNER_SECURITY_LOGS,\n payload: securityLogs,\n});\n\ninterface SetErrorPartnerAction {\n type: PartnerActionTypes;\n payload: string;\n}\n\nexport const setPartnerError = (\n errorMessage: string\n): SetErrorPartnerAction => ({\n type: PartnerActionTypes.SET_PARTNER_ERROR,\n payload: errorMessage,\n});\n\ninterface SetCurrentPartnerAction {\n type: PartnerActionTypes;\n payload: UserPartner | undefined;\n}\n\nexport const setCurrentPartner = (\n userPartner?: UserPartner\n): SetCurrentPartnerAction => {\n if (userPartner) {\n localService.setCurrentPartner(userPartner);\n }\n\n return {\n type: PartnerActionTypes.SET_CURRENT_PARTNER,\n payload: userPartner,\n };\n};\n\ninterface SetCurrentDashboardPartnerAction {\n type: PartnerActionTypes;\n payload: boolean;\n}\n\nconst setDashboardPartnerCreateState = (\n isCreateMode: boolean\n): SetCurrentDashboardPartnerAction => {\n return {\n type: PartnerActionTypes.SET_DASHBOARD_PARTNER_CREATE,\n payload: isCreateMode,\n };\n};\n\nexport const setDashboardPartnerCreate: ActionCreator<\n ThunkAction, AppState, null, LoadPartnerAction>\n> = (isCreateMode: boolean) => {\n return async (dispatch: Dispatch) => {\n try {\n dispatch(setDashboardPartnerCreateState(isCreateMode));\n } catch (err) {\n console.error(err);\n }\n };\n};\n\nexport const loadPartner: ActionCreator<\n ThunkAction, AppState, null, LoadPartnerAction>\n> = (partnerId: string) => {\n return async (dispatch: Dispatch) => {\n try {\n dispatch(setPartnerLoading(true));\n const partner = await partnerService.getPartnerById(partnerId);\n dispatch(setPartner(partner));\n } catch (err) {\n console.error(err);\n }\n };\n};\n\ninterface LoadPartnerSecurityLogsAction {\n type: PartnerActionTypes;\n}\n\nexport const loadPartnerSecurityLogs: ActionCreator<\n ThunkAction, AppState, null, LoadPartnerSecurityLogsAction>\n> = (partnerId: string) => {\n return async (dispatch: Dispatch) => {\n try {\n const securityLogs = await partnerService.getPartnerSecurityLogs(\n partnerId\n );\n dispatch(setPartnerSecurityLogs(securityLogs));\n } catch (err) {\n console.error(err);\n }\n };\n};\n\ninterface AddMemberSuccessAction {\n type: PartnerActionTypes;\n payload: PartnerMember;\n}\n\nconst addMemberSuccess = (member: PartnerMember): AddMemberSuccessAction => ({\n type: PartnerActionTypes.ADD_MEMBER_SUCCESS,\n payload: member,\n});\n\ninterface AddMemberLoadingAction {\n type: PartnerActionTypes;\n payload: boolean;\n}\n\nconst addMemberLoading = (loading: boolean): AddMemberLoadingAction => ({\n type: PartnerActionTypes.ADD_MEMBER_LOADING,\n payload: loading,\n});\n\ninterface AddMemberErrorAction {\n type: PartnerActionTypes;\n payload: string;\n}\n\nexport const addMemberError = (errorMessage: string): AddMemberErrorAction => ({\n type: PartnerActionTypes.ADD_MEMBER_ERROR,\n payload: errorMessage,\n});\n\nexport const addMember: ActionCreator<\n ThunkAction, AppState, null, AddMemberSuccessAction>\n> = (partnerId: string, newMember: NewPartnerMember, callback: () => void) => {\n return async (dispatch: Dispatch) => {\n try {\n dispatch(addMemberLoading(true));\n const member = await partnerService.addNewMember(partnerId, newMember);\n dispatch(addMemberSuccess(member));\n callback();\n } catch (err: any) {\n dispatch(addMemberError(err?.response?.data?.message));\n console.error(err.response);\n }\n };\n};\n\ninterface AddApplicationSuccessAction {\n type: PartnerActionTypes;\n payload: PartnerApplication;\n}\n\nexport const addApplicationSuccess = (\n application: PartnerApplication\n): AddApplicationSuccessAction => ({\n type: PartnerActionTypes.ADD_APPLICATION_SUCCESS,\n payload: application,\n});\n\ninterface AddApplicationLoadingAction {\n type: PartnerActionTypes;\n payload: boolean;\n}\n\nexport const addApplicationLoading = (\n loading: boolean\n): AddApplicationLoadingAction => ({\n type: PartnerActionTypes.ADD_APPLICATION_LOADING,\n payload: loading,\n});\n\ninterface AddApplicationErrorAction {\n type: PartnerActionTypes;\n payload: string;\n}\n\nexport const addApplicationError = (\n errorMessage: string\n): AddApplicationErrorAction => ({\n type: PartnerActionTypes.ADD_APPLICATION_ERROR,\n payload: errorMessage,\n});\n\ninterface RemoveMemberSuccessAction {\n type: PartnerActionTypes;\n payload: {\n userId: string;\n email: string;\n };\n}\n\nconst removeMemberSuccess = (\n removedMemberId: string,\n removedMemberEmail: string\n): RemoveMemberSuccessAction => ({\n type: PartnerActionTypes.REMOVE_MEMBER_SUCCESS,\n payload: {\n userId: removedMemberId,\n email: removedMemberEmail,\n },\n});\n\ninterface RemoveMemberLoadingAction {\n type: PartnerActionTypes;\n payload: string;\n}\n\nconst removeMemberLoading = (\n removedMemberEmail: string\n): RemoveMemberLoadingAction => ({\n type: PartnerActionTypes.REMOVE_MEMBER_LOADING,\n payload: removedMemberEmail,\n});\n\ninterface RemoveMemberErrorAction {\n type: PartnerActionTypes;\n payload: string;\n}\n\nconst removeMemberError = (errorMessage: string): RemoveMemberErrorAction => ({\n type: PartnerActionTypes.REMOVE_MEMBER_ERROR,\n payload: errorMessage,\n});\n\nexport const removeMember: ActionCreator<\n ThunkAction, AppState, null, RemoveMemberSuccessAction>\n> = (\n partnerId: string,\n memberId: string,\n memberEmail: string,\n withdrawEmail: string | undefined\n) => {\n return async (dispatch: Dispatch) => {\n try {\n dispatch(removeMemberLoading(memberEmail));\n await partnerService.removeMember(partnerId, memberId, withdrawEmail);\n dispatch(removeMemberSuccess(memberId, memberEmail));\n } catch (err: any) {\n dispatch(removeMemberError(err.message));\n console.error(err);\n }\n };\n};\n\ninterface UpdateMemberRoleSuccessAction {\n type: PartnerActionTypes;\n payload: PartnerMember;\n}\n\nconst updateMemberRoleSuccess = (\n member: PartnerMember\n): UpdateMemberRoleSuccessAction => ({\n type: PartnerActionTypes.UPDATE_MEMBER_ROLE_SUCCESS,\n payload: member,\n});\n\ninterface UpdateMemberRoleLoadingAction {\n type: PartnerActionTypes;\n payload: boolean;\n}\n\nconst updateMemberRoleLoading = (\n loading: boolean\n): UpdateMemberRoleLoadingAction => ({\n type: PartnerActionTypes.UPDATE_MEMBER_ROLE_LOADING,\n payload: loading,\n});\n\ninterface UpdateMemberRoleErrorAction {\n type: PartnerActionTypes;\n payload: string;\n}\n\nexport const updateMemberRoleError = (\n errorMessage: string\n): UpdateMemberRoleErrorAction => ({\n type: PartnerActionTypes.UPDATE_MEMBER_ROLE_ERROR,\n payload: errorMessage,\n});\n\nexport const updateMemberRole: ActionCreator<\n ThunkAction, AppState, null, UpdateMemberRoleSuccessAction>\n> = (partnerId: string, updatedMember: PartnerMember, callback: () => void) => {\n return async (dispatch: Dispatch) => {\n try {\n dispatch(updateMemberRoleLoading(true));\n const member = await partnerService.updateMember(\n partnerId,\n updatedMember\n );\n dispatch(updateMemberRoleSuccess(member));\n callback();\n } catch (err: any) {\n dispatch(updateMemberRoleError(err.response?.data?.message || err));\n console.error(err.response);\n }\n };\n};\n\nexport const loadUserPartners: ActionCreator<\n ThunkAction, AppState, null, LoadUserPartnersAction>\n> = (currentPartnerId?: string) => {\n return async (dispatch: Dispatch) => {\n try {\n dispatch(setPartnersLoading(true));\n const partners = await partnerService.getUserPartners();\n dispatch(setUserPartners(partners));\n if (partners && partners.length === 0) {\n dispatch(setPartnerLoading(false));\n } else {\n const wantedPartnerId =\n currentPartnerId || localService.getCurrentPartner()?.id;\n\n const currentPartner = wantedPartnerId\n ? partners.find((p) => p.id === wantedPartnerId) || partners[0]\n : partners[0];\n\n if (currentPartner) {\n dispatch(setCurrentPartner(currentPartner));\n dispatch(setPartnerLoading(false));\n }\n }\n } catch (err) {\n console.error(err);\n }\n };\n};\n\ninterface SetInvitationStatusAction {\n type: PartnerActionTypes;\n payload: MemberStatus;\n}\n\ninterface MemberInvitationLoadingAction {\n type: PartnerActionTypes;\n payload: boolean;\n}\n\nconst setInvitationLoading = (\n loading: boolean\n): MemberInvitationLoadingAction => ({\n type: PartnerActionTypes.SET_INVITATION_LOADING,\n payload: loading,\n});\n\nconst setInvitationStatus = (\n invitationStatus: MemberStatus\n): SetInvitationStatusAction => ({\n type: PartnerActionTypes.SET_INVITATION_STATUS,\n payload: invitationStatus,\n});\n\nexport const handleMemberInvitationAccepted: ActionCreator<\n ThunkAction, AppState, null, SetInvitationStatusAction>\n> = (partnerId: string, email: string, currentEmail: string) => {\n return async (dispatch: Dispatch) => {\n try {\n dispatch(setInvitationLoading(true));\n\n const decodedEmail = decodeURIComponent(email);\n if (decodedEmail.toLowerCase() !== currentEmail.toLowerCase()) {\n dispatch(\n setBasicAlert({\n messageKey: 'wrongUserInvitation',\n severity: 'error',\n })\n );\n dispatch(setInvitationStatus(MemberStatus.NOT_FOUND));\n return;\n }\n const status = await partnerService.processInvitation(\n partnerId,\n decodedEmail\n );\n dispatch(setInvitationStatus(status));\n if (status === MemberStatus.NOT_FOUND) {\n dispatch(\n setBasicAlert({\n messageKey: 'invitationExpiredMessage',\n severity: 'error',\n })\n );\n }\n dispatch(setInvitationLoading(false));\n } catch (err) {\n console.error(err);\n dispatch(\n setBasicAlert({\n messageKey: 'generalErrorMessage',\n severity: 'error',\n })\n );\n dispatch(setInvitationStatus(MemberStatus.NOT_FOUND));\n }\n };\n};\n\nexport type PartnerActions =\n | LoadUserPartnersAction\n | LoadPartnerAction\n | SetLoadingPartnerAction\n | SetLoadingPartnerFormSubmissionAction\n | SetErrorPartnerAction\n | AddMemberSuccessAction\n | AddMemberLoadingAction\n | AddMemberErrorAction\n | RemoveMemberSuccessAction\n | RemoveMemberLoadingAction\n | RemoveMemberErrorAction\n | UpdateMemberRoleSuccessAction\n | UpdateMemberRoleLoadingAction\n | UpdateMemberRoleErrorAction\n | AddApplicationSuccessAction\n | AddApplicationLoadingAction\n | AddApplicationErrorAction\n | SetCurrentPartnerAction\n | SetCurrentDashboardPartnerAction\n | SetPartnerSecurityLogsAction\n | SetInvitationStatusAction\n | MemberInvitationLoadingAction;\n","import { Theme } from '@mui/material/styles';\nimport { theme as msgTheme } from './configuration/themes/msg/theme';\nimport { theme as inPunctoTheme } from './configuration/themes/inPuncto/theme';\nimport { appConfiguration } from './configuration';\n\n/**\n * @description This represents the custom distances from the theme\n * @example padding: Distances.BIG\n */\nexport enum Distances {\n ///////////////////////////////////////////////////////\n ///////////// Custom Distances /////////////////////////\n ///////////////////////////////////////////////////////\n BIG = '80px',\n FIELD = '55px',\n HALF_FIELD_30 = '30px',\n HALF_FIELD_20 = '20px',\n INPUT = '10px',\n BUTTON_LENGTH = '190px',\n}\n\ndeclare module '@mui/material/styles/createPalette' {\n interface Palette {\n red: Palette['primary'];\n yellow: Palette['primary'];\n accentYellow: Palette['primary'];\n lightRed: Palette['primary'];\n accentRed: Palette['primary'];\n accentGreen: Palette['primary'];\n infoGreen: Palette['primary'];\n white: Palette['primary'];\n disabled: Palette['primary'];\n middleGrey: Palette['primary'];\n border: Palette['primary'];\n darkGrey: Palette['primary'];\n typography: Palette['primary'];\n lightBrown: Palette['primary'];\n }\n interface PaletteOptions {\n red: PaletteOptions['primary'];\n yellow: PaletteOptions['primary'];\n accentYellow: PaletteOptions['primary'];\n lightRed: PaletteOptions['primary'];\n accentRed: PaletteOptions['primary'];\n accentGreen: PaletteOptions['primary'];\n infoGreen: PaletteOptions['primary'];\n white: PaletteOptions['primary'];\n disabled: PaletteOptions['primary'];\n middleGrey: PaletteOptions['primary'];\n border: PaletteOptions['primary'];\n darkGrey: PaletteOptions['primary'];\n typography: PaletteOptions['primary'];\n lightBrown: PaletteOptions['primary'];\n }\n}\n\ndeclare module '@mui/material/styles/createTypography' {\n interface Typography {\n header0: React.CSSProperties;\n header1: React.CSSProperties;\n header1smaller: React.CSSProperties;\n header2: React.CSSProperties;\n profile: React.CSSProperties;\n header3: React.CSSProperties;\n text: React.CSSProperties;\n menu: React.CSSProperties;\n textBold: React.CSSProperties;\n noteItalic: React.CSSProperties;\n buttons: React.CSSProperties;\n search: React.CSSProperties;\n labelButton: React.CSSProperties;\n }\n interface TypographyOptions {\n header0?: React.CSSProperties;\n header1?: React.CSSProperties;\n header1smaller?: React.CSSProperties;\n header2?: React.CSSProperties;\n profile?: React.CSSProperties;\n header3?: React.CSSProperties;\n text?: React.CSSProperties;\n textBold?: React.CSSProperties;\n noteItalic?: React.CSSProperties;\n menu?: React.CSSProperties;\n buttons?: React.CSSProperties;\n search?: React.CSSProperties;\n labelButton?: React.CSSProperties;\n }\n}\n\ndeclare module '@mui/material/Typography/Typography' {\n interface TypographyPropsVariantOverrides {\n header0: true;\n header1: true;\n header1smaller: true;\n header2: true;\n profile: true;\n header3: true;\n text: true;\n textBold: true;\n noteItalic: true;\n menu: true;\n buttons: true;\n search: true;\n labelButton: true;\n }\n}\n\nconst themes: { [env: string]: Theme } = {\n msg: msgTheme,\n inPuncto: inPunctoTheme,\n};\n\nexport const theme = themes[appConfiguration()?.theme || 'msg'];\n","import { createTheme } from '@mui/material/styles';\n\n// eslint-disable-next-line import/no-unused-modules\nexport const theme = createTheme({\n breakpoints: {\n values: {\n xs: 0,\n sm: 600,\n md: 900,\n lg: 1200,\n xl: 1800,\n },\n },\n\n /**\n * @description This represents the custom colors from the theme\n * @example color: theme.palette.yellow.main\n */\n palette: {\n ///////////////////////////////////////////////////////\n ///////////////// Custom Colors ///////////////////////\n ///////////////////////////////////////////////////////\n primary: {\n light: '#9c4360',\n main: '#A01441', //Primary red\n dark: '#5c0e27',\n },\n secondary: {\n light: '#b3d3df',\n main: '#56A3BC', //Accent blue\n dark: '#3f7e96',\n },\n yellow: {\n main: '#F7CD7F',\n },\n red: {\n main: '#e74337',\n },\n accentYellow: {\n main: '#F3AC57',\n },\n lightRed: {\n main: '#ED6C96',\n },\n accentRed: {\n main: '#DB1B59',\n },\n accentGreen: {\n main: '#82A7A6',\n },\n infoGreen: {\n main: '#74CD63',\n },\n white: {\n main: '#FFFFFF',\n },\n disabled: {\n main: '#F1F1F1',\n },\n middleGrey: {\n main: '#E6E6E6',\n },\n border: {\n main: '#BABABA',\n },\n darkGrey: {\n main: '#6F6F6F',\n },\n typography: {\n main: '#1C1F37',\n },\n lightBrown: {\n main: '#C6B89F',\n },\n ///////////////////////////////////////////////////////\n error: {\n main: '#c4000e',\n },\n success: {\n main: '#5cb85c',\n },\n grey: {\n '50': '#fafafa',\n '100': '#f2f2f2',\n '200': '#eeeeee',\n '300': '#e0e0e0',\n '400': '#bdbdbd',\n '500': '#9f9f9f',\n '600': '#757575',\n '700': '#616161',\n '800': '#424242',\n '900': '#212121',\n A100: 'rgba(234, 234, 234, 0.25)',\n A200: '#CBCBCB',\n A400: '#6F6F6F',\n },\n text: {\n primary: '#1C1F37',\n },\n background: {\n default: '#FCFCFC', //needs to be the new color for the background but needs careful verification at redesign\n paper: '#ffffff', //'#FCFCFC'\n },\n },\n /**\n * @description This represents the custom typography from the theme\n * @example Hello \n */\n typography: {\n fontFamily: ['\"Open Sans\"', 'Roboto', 'Arial', 'sans-serif'].join(','),\n fontSize: 16,\n ///////////////////////////////////////////////////////\n ///////////// Custom Variants /////////////////////////\n ///////////////////////////////////////////////////////\n header0: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '40px',\n fontWeight: 'bold',\n },\n header1: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '32px',\n fontWeight: 'bold',\n },\n header1smaller: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '24px',\n fontWeight: 'bold',\n },\n header2: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '18px',\n fontWeight: 'bold',\n },\n header3: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '16px',\n fontWeight: 'bold',\n },\n profile: {\n fontFamily: ['Inter', 'sans-serif'].join(','),\n fontSize: '14px',\n fontWeight: 'bold',\n },\n textBold: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '14px',\n fontWeight: 'bold',\n lineHeight: '20px',\n },\n text: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '14px',\n fontWeight: '400',\n lineHeight: '20px',\n },\n noteItalic: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '11px',\n fontWeight: '400',\n fontStyle: 'italic',\n },\n menu: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '11px',\n fontWeight: 'bold',\n textTransform: 'uppercase',\n },\n buttons: {\n fontFamily: ['Montserrat', 'sans-serif'].join(','),\n fontSize: '10px',\n fontWeight: 'bold',\n textTransform: 'uppercase',\n minWidth: 'max-content',\n },\n labelButton: {\n fontFamily: ['Montserrat', 'sans-serif'].join(','),\n fontSize: '14px',\n textDecoration: 'underline',\n cursor: 'pointer',\n },\n ///////////////////////////////////////////////////////\n h5: {\n fontSize: '1.5rem',\n },\n h6: {\n fontSize: '1rem',\n },\n },\n});\n","import { createTheme } from '@mui/material/styles';\n\ndeclare module '@mui/material/styles/createPalette' {\n interface Palette {\n yellow: Palette['primary'];\n accentYellow: Palette['primary'];\n lightRed: Palette['primary'];\n accentRed: Palette['primary'];\n accentGreen: Palette['primary'];\n infoGreen: Palette['primary'];\n white: Palette['primary'];\n disabled: Palette['primary'];\n middleGrey: Palette['primary'];\n border: Palette['primary'];\n darkGrey: Palette['primary'];\n typography: Palette['primary'];\n }\n interface PaletteOptions {\n yellow: PaletteOptions['primary'];\n accentYellow: PaletteOptions['primary'];\n lightRed: PaletteOptions['primary'];\n accentRed: PaletteOptions['primary'];\n accentGreen: PaletteOptions['primary'];\n infoGreen: PaletteOptions['primary'];\n white: PaletteOptions['primary'];\n disabled: PaletteOptions['primary'];\n middleGrey: PaletteOptions['primary'];\n border: PaletteOptions['primary'];\n darkGrey: PaletteOptions['primary'];\n typography: PaletteOptions['primary'];\n }\n}\n\ndeclare module '@mui/material/styles/createTypography' {\n interface Typography {\n header0: React.CSSProperties;\n header1: React.CSSProperties;\n header1smaller: React.CSSProperties;\n header2: React.CSSProperties;\n profile: React.CSSProperties;\n header3: React.CSSProperties;\n text: React.CSSProperties;\n menu: React.CSSProperties;\n textBold: React.CSSProperties;\n noteItalic: React.CSSProperties;\n buttons: React.CSSProperties;\n search: React.CSSProperties;\n labelButton: React.CSSProperties;\n }\n interface TypographyOptions {\n header0?: React.CSSProperties;\n header1?: React.CSSProperties;\n header1smaller?: React.CSSProperties;\n header2?: React.CSSProperties;\n profile?: React.CSSProperties;\n header3?: React.CSSProperties;\n text?: React.CSSProperties;\n textBold?: React.CSSProperties;\n noteItalic?: React.CSSProperties;\n menu?: React.CSSProperties;\n buttons?: React.CSSProperties;\n search?: React.CSSProperties;\n labelButton?: React.CSSProperties;\n }\n}\n\ndeclare module '@mui/material/Typography/Typography' {\n interface TypographyPropsVariantOverrides {\n header0: true;\n header1: true;\n header1smaller: true;\n header2: true;\n profile: true;\n header3: true;\n text: true;\n textBold: true;\n noteItalic: true;\n menu: true;\n buttons: true;\n search: true;\n labelButton: true;\n }\n}\n\nexport const theme = createTheme({\n breakpoints: {\n values: {\n xs: 0,\n sm: 600,\n md: 900,\n lg: 1200,\n xl: 1800,\n },\n },\n\n /**\n * @description This represents the custom colors from the theme\n * @example color: theme.palette.yellow.main\n */\n palette: {\n ///////////////////////////////////////////////////////\n ///////////////// Custom Colors ///////////////////////\n ///////////////////////////////////////////////////////\n primary: {\n light: '#404040',\n main: '#404040', //'#005c99', //'#890b0b', //Primary red\n dark: '#161d7a', //'#680404', // change this //#680404 //#040b68\n },\n secondary: {\n light: '#b3d3df',\n main: '#005c99', //Accent blue\n dark: '#3f7e96',\n },\n yellow: {\n main: '#358fe8', //'#F7CD7F',\n },\n red: {\n main: '#e74337',\n },\n accentYellow: {\n main: '#F3AC57',\n },\n lightRed: {\n main: '#358fe8', //'#e83535', //#358fe8\n light: '#ffffff',\n },\n accentRed: {\n main: '#161d7a', //'#680404', //#040b68\n },\n accentGreen: {\n main: '#82A7A6',\n },\n infoGreen: {\n main: '#74CD63',\n },\n white: {\n main: '#FFFFFF',\n },\n disabled: {\n main: '#F1F1F1',\n },\n middleGrey: {\n main: '#E6E6E6',\n },\n border: {\n main: '#BABABA',\n },\n darkGrey: {\n main: '#6F6F6F',\n },\n typography: {\n main: '#1C1F37',\n },\n lightBrown: {\n main: '#C6B89F',\n },\n ///////////////////////////////////////////////////////\n error: {\n main: '#c4000e',\n },\n success: {\n main: '#5cb85c',\n },\n grey: {\n '50': '#fafafa',\n '100': '#f2f2f2',\n '200': '#eeeeee',\n '300': '#e0e0e0',\n '400': '#bdbdbd',\n '500': '#9f9f9f',\n '600': '#757575',\n '700': '#616161',\n '800': '#424242',\n '900': '#212121',\n A100: 'rgba(234, 234, 234, 0.25)',\n A200: '#CBCBCB',\n A400: '#6F6F6F',\n },\n text: {\n primary: '#1C1F37',\n },\n background: {\n default: '#FCFCFC', //needs to be the new color for the background but needs careful verification at redesign\n paper: '#ffffff', //'#FCFCFC'\n },\n },\n /**\n * @description This represents the custom typography from the theme\n * @example Hello \n */\n typography: {\n fontFamily: ['\"Open Sans\"', 'Roboto', 'Arial', 'sans-serif'].join(','),\n fontSize: 16,\n ///////////////////////////////////////////////////////\n ///////////// Custom Variants /////////////////////////\n ///////////////////////////////////////////////////////\n header0: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '40px',\n fontWeight: 'bold',\n },\n header1: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '32px',\n fontWeight: 'bold',\n },\n header1smaller: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '24px',\n fontWeight: 'bold',\n },\n header2: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '18px',\n fontWeight: 'bold',\n lineHeight: '22px',\n },\n header3: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '16px',\n fontWeight: 'bold',\n lineHeight: '20px',\n },\n textBold: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '14px',\n fontWeight: 'bold',\n lineHeight: '20px',\n },\n profile: {\n fontFamily: ['Inter', 'sans-serif'].join(','),\n fontSize: '14px',\n fontWeight: 'bold',\n lineHeight: '20px',\n },\n text: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '14px',\n fontWeight: '400',\n },\n noteItalic: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '11px',\n fontWeight: '400',\n fontStyle: 'italic',\n },\n menu: {\n fontFamily: ['Calibri', 'sans-serif'].join(','),\n fontSize: '11px',\n fontWeight: 'bold',\n textTransform: 'uppercase',\n },\n buttons: {\n fontFamily: ['Montserrat', 'sans-serif'].join(','),\n fontSize: '10px',\n fontWeight: 'bold',\n textTransform: 'uppercase',\n minWidth: 'max-content',\n },\n labelButton: {\n fontFamily: ['Montserrat', 'sans-serif'].join(','),\n fontSize: '14px',\n textDecoration: 'underline',\n cursor: 'pointer',\n },\n ///////////////////////////////////////////////////////\n h5: {\n fontSize: '1.5rem',\n },\n h6: {\n fontSize: '1rem',\n },\n },\n});\n","import { BillingSystem, PaymentMethodType } from '../models/enums';\n\nexport const SHORT_MONTH_KEYS = [\n 'shortJanuary',\n 'shortFebruary',\n 'shortMarch',\n 'shortApril',\n 'shortMay',\n 'shortJune',\n 'shortJuly',\n 'shortAugust',\n 'shortSeptember',\n 'shortOctober',\n 'shortNovember',\n 'shortDecember',\n];\nexport const IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/tiff'];\nexport const DOCUMENT_MIME_TYPES = ['application/pdf'];\nexport const EURO_ISO_4217 = 'eur';\nexport const NUMBER_OF_NOTIFICATIONS_IN_ONE_BATCH = 10;\nexport const SERVICE_SPECIFICATION_VALIDATION_TIMEOUT = 1000 * 60 * 2;\nexport const BILLING_SYSTEM_PAYMENT_METHODS = {\n [BillingSystem.NONE]: [PaymentMethodType.WIRE_TRANSFER],\n [BillingSystem.MSG]: [PaymentMethodType.WIRE_TRANSFER],\n [BillingSystem.STRIPE]: [\n PaymentMethodType.CARD,\n PaymentMethodType.SEPA,\n PaymentMethodType.WIRE_TRANSFER,\n ],\n};\nexport const MAX_BLOCKS_PER_PRODUCT = 3;\nexport const MAX_FILE_SIZE = 20 * 1024 * 1024;\nexport const MAX_FILE_SIZE_MB = 20;\nexport const DEFAULT_PRICE_PLAN_NAME = 'Standard Pricing';\nexport const SNACKBAR_EXPIRATION_TIME_MS = 3000;\nexport const MIN_CONTACT_FORM_MESSAGE_LENGTH = 10;\nexport const MAX_CONTACT_FORM_MESSAGE_LENGTH = 10000;\nexport const MAX_FILTER_OPTIONS_SELECTIONS_FOR_LABEL = 9;\nexport const MAX_PRODUCT_CARDS_PER_ROW = 5;\nexport const FILTER_QUERY_PARAMETER_KEY = 'filter';\nexport const DAYS_UNTIL_PRODUCT_IS_CONSIDERED_NEW = 14;\nexport const MAX_ADVANTAGES = 4;\n\n// Files universal i18n labels\nexport const TERMS_AND_CONDITIONS_I18N_LABEL = 'terms&Conditions';\nexport const SERVICE_LEVEL_AGREEMENT_I18N_LABEL = 'serviceLevelAgreement';\nexport const DATA_PROCESSING_SPECIFICATION_I18N_LABEL =\n 'dataProcessingSpecification';\nexport const ADDITIONAL_DOCUMENTS_I18N_LABEL = 'additionalDocuments';\n\nexport const CARD_WIDTH = '262px';\nexport const CARD_HEIGHT = '357px';\nexport const CARD_WIDTH_WITH_LATERAL_MARGINS = '272px';\nexport const COOKIE_EXPIRATION_IN_MSEC = 34560000000; //Calculation for : 400(days) * 24 * 60 * 60 * 1000\nexport const COOKIE_USER_PREFERENCE = 'cookieUserPreference';\nexport const COOKIE_ACCEPT_ALL = 'allAccepted';\nexport const COOKIE_ONLY_NECESSARY = 'onlyNecessary';\nexport const UNIQUE_CROPPED_IMAGE_FILE_NAME =\n 'MP_CROPPED_IMAGE_UNIQUE_FILE_NAME';\n","import { BasicAlert, SignalRAlert } from '../reducers/notificationsReducer';\n\nexport enum NotificationsActionTypes {\n SET_SIGNALR_ALERT = 'SET_SIGNALR_ALERT',\n CLEAR_SIGNALR_ALERT = 'CLEAR_SIGNALR_ALERT',\n SET_BASIC_ALERT = 'SET_BASIC_ALERT',\n CLEAR_BASIC_ALERT = 'CLEAR_BASIC_ALERT',\n}\n\ninterface SetAlertAction {\n type: NotificationsActionTypes;\n alert: BasicAlert;\n}\n\nexport const setSignalRAlert = (alert: SignalRAlert): SetAlertAction => ({\n type: NotificationsActionTypes.SET_SIGNALR_ALERT,\n alert,\n});\n\nexport const setBasicAlert = (alert: BasicAlert): SetAlertAction => ({\n type: NotificationsActionTypes.SET_BASIC_ALERT,\n alert,\n});\n\ninterface ClearAlertAction {\n type: NotificationsActionTypes;\n}\n\nexport const clearSignalRAlert = (): ClearAlertAction => ({\n type: NotificationsActionTypes.CLEAR_SIGNALR_ALERT,\n});\n\nexport const clearBasicAlert = (): ClearAlertAction => ({\n type: NotificationsActionTypes.CLEAR_BASIC_ALERT,\n});\n\nexport type NotificationsActions = SetAlertAction;\n","import { AvailabilityStatus, MemberStatus } from '../models/enums';\nimport { Role } from '../models/partner';\nimport { AppState } from './index';\n\n// User selectors\nexport const userSelector = (state: AppState) => state.auth?.user;\nexport const tokenAcquiredSelector = (state: AppState) =>\n state.auth.tokenAcquired;\n\n// Product selectors\nexport const productsSelector = (state: AppState) => state.products.products;\nexport const productSelector = (id: string, state: AppState) => {\n return id\n ? state.products.product && state.products.product.id === id\n ? state.products.product\n : undefined\n : undefined;\n};\nexport const productsLoadingSelector = (state: AppState) =>\n state.products.loading;\nexport const productsResponseSelector = (state: AppState) =>\n state.products.loadProductErrorMessage;\n\n// Dashboard Products selector\nexport const dashboardProductsSelector = (state: AppState) =>\n state.dashboardProducts.products;\nexport const dashboardProductsLoadingSelector = (state: AppState) =>\n state.dashboardProducts.loading;\nexport const dashboardProductsErrorSelector = (state: AppState) =>\n state.dashboardProducts.error;\n\n// Dashboard Products selector\nexport const dashboardStatisticsSelector = (state: AppState) =>\n state.dashboardStatistics.statistics;\nexport const dashboardStatisticsLoadingSelector = (state: AppState) =>\n state.dashboardStatistics.loading;\n\n// Payment method selectors\nexport const sepaBankAccountsSelector = (state: AppState) =>\n state.paymentMethods.bankAccounts;\nexport const creditCardsSelector = (state: AppState) =>\n state.paymentMethods.cards;\nexport const paymentMethodsLoadingSelector = (state: AppState) =>\n state.paymentMethods.loading;\nexport const selectedPaymentMethodSelector = (state: AppState) =>\n state.paymentMethods.selectedPaymentMethod;\n\n// Subscription selectors\nexport const subscriptionsSelector = (state: AppState) =>\n state.subscriptions.subscriptions;\nexport const subscriptionsLoadingSelector = (state: AppState) =>\n state.subscriptions.subscriptionsLoading;\nexport const subscriptionCreateLoadingSelector = (state: AppState) =>\n state.subscriptions.loadingCreateSubscription;\nexport const subscriptionPrimaryKeyLoadingSelector = (\n subscriptionId: string\n) => {\n return (state: AppState) =>\n state.subscriptions.subscriptionDetailsStatus[subscriptionId]\n .loadingPrimaryKey;\n};\nexport const subscriptionSecondaryKeyLoadingSelector = (\n subscriptionId: string\n) => {\n return (state: AppState) =>\n state.subscriptions.subscriptionDetailsStatus[subscriptionId]\n .loadingSecondaryKey;\n};\nexport const getSubscriptionKeysErrorSelector = (subscriptionId: string) => {\n return (state: AppState) =>\n state.subscriptions.subscriptionDetailsStatus[subscriptionId]\n .subscriptionKeyLoadError;\n};\nexport const subscriptionCreateErrorMessage = (state: AppState) =>\n state.subscriptions.subscriptionCreateErrorMessage;\n\n// Partner\nexport const partnerSelector = (state: AppState) => state.partner.partner;\nexport const partnerLoadingSelector = (state: AppState) =>\n state.partner.loadingPartner;\nexport const partnerFormSubmissionLoadingSelector = (state: AppState) =>\n state.partner.loadingPartnerFormSubmission;\nexport const partnersLoadingSelector = (state: AppState) =>\n state.partner.loadingPartners;\nexport const partnerErrorSelector = (state: AppState) => state.partner.error;\nexport const addMemberLoadingSelector = (state: AppState) =>\n state.partner.addMemberLoading;\nexport const addMemberErrorSelector = (state: AppState) =>\n state.partner.addMemberError;\nexport const removeMemberLoadingSelector = (state: AppState) =>\n state.partner.removeMemberEmail;\nexport const removeMemberErrorSelector = (state: AppState) =>\n state.partner.removeMemberError;\nexport const updateMemberRoleLoadingSelector = (state: AppState) =>\n state.partner.updateMemberRoleLoading;\nexport const updateMemberRoleErrorSelector = (state: AppState) =>\n state.partner.updateMemberRoleError;\n export const addApplicationLoadingSelector = (state: AppState) =>\n state.partner.addApplicationLoading;\n export const addApplicationErrorSelector = (state: AppState) =>\n state.partner.addApplicationError;\nexport const hasOwnerRoleSelector = (state: AppState) => {\n if (state && state.auth && state.auth.user) {\n const userId = state.auth.user.id;\n const member =\n state.partner.partner &&\n state.partner.partner.members &&\n state.partner.partner.members.find((member) => member.user.id === userId);\n return (\n member &&\n member.roles[0].role === Role.OWNER &&\n member.status === MemberStatus.ACTIVE\n );\n } else {\n return false;\n }\n};\nexport const hasMaintainerRoleSelector = (state: AppState) => {\n if (state && state.auth && state.auth.user) {\n const userId = state.auth.user.id;\n const member =\n state.partner.partner &&\n state.partner.partner.members &&\n state.partner.partner.members.find((member) => member.user.id === userId);\n return (\n member &&\n member.roles[0].role === Role.MAINTAINER &&\n member.status === MemberStatus.ACTIVE\n );\n } else {\n return false;\n }\n};\n\nexport const hasMaintainableProductsSelector = (state: AppState) => {\n if (state && state.auth && state.auth.user) {\n let hasServices = false;\n const currentPartner = state.partner.currentPartner;\n if (currentPartner) {\n const currentUserPartner =\n state.partner.userPartners &&\n state.partner.userPartners.find(\n (partner) => partner.id === currentPartner.id\n );\n hasServices = !!currentPartner.hasServices;\n if (\n currentUserPartner &&\n (currentUserPartner.roles[0].role === Role.MAINTAINER ||\n currentUserPartner.roles[0].role === Role.OWNER) &&\n hasServices\n )\n return true;\n }\n }\n return false;\n};\n\nexport const isPartnerDisabledSelector = (state: AppState) => {\n return (\n state.partner.currentPartner?.availabilityStatus ===\n AvailabilityStatus.DISABLED\n );\n};\nexport const partnerCurrentPartner = (state: AppState) =>\n state.partner.currentPartner;\nexport const userPartnersSelector = (state: AppState) =>\n state.partner.userPartners;\nexport const partnerDashboardCreateState = (state: AppState) =>\n state.partner.dashboardPartnerCreateMode;\nexport const partnerSecurityLogs = (state: AppState) =>\n state.partner.securityLogs;\nexport const invitationStatusSelector = (state: AppState) =>\n state.partner.invitationStatus;\n\n// Subscriptions Usages selector\nexport const usagesBySubscriptionsSelector = (state: AppState) =>\n state.subscriptionsUsages.usagesBySubscriptions;\nexport const usagesLoadingSelector = (state: AppState) =>\n state.subscriptionsUsages.loading;\nexport const usagesByProductsSelector = (state: AppState) =>\n state.subscriptionsUsages.usagesByProducts;\n\n// Subscriptions Costs selector\nexport const costsBySubscriptionsSelector = (state: AppState) =>\n state.subscriptionsCosts.costsBySubscriptions;\nexport const costsLoadingSelector = (state: AppState) =>\n state.subscriptionsCosts.loading;\nexport const costsByProductsSelector = (state: AppState) =>\n state.subscriptionsCosts.costsByProducts;\n\n// Api Specifications selectors\nexport const specificationByProductIdSelector = (\n productId: string,\n state: AppState\n) => {\n return productId\n ? state.productsApiSpecification.productsApiSpecification[productId]\n : undefined;\n};\n\n// Notifications\nexport const notificationsSignalRAlertSelector = (state: AppState) =>\n state.notifications.signalRAlert;\nexport const notificationsBasicAlertSelector = (state: AppState) =>\n state.notifications.basicAlert;\n\n// User notifications\nexport const notificationsSelector = (state: AppState) =>\n state.userNotifications.notifications;\nexport const notificationsNumberSelector = (state: AppState) =>\n state.userNotifications.numberOfNotificationsInLastBatch;\nexport const notificationsUnreadSelector = (state: AppState) =>\n state.userNotifications.numberOfUnreadNotifications;\nexport const notificationCurrentPageSelector = (state: AppState) =>\n state.userNotifications.currentPage;\nexport const notificationhasMorePagesSelector = (state: AppState) =>\n state.userNotifications.hasMorePages;\n","import { push } from 'connected-react-router';\nimport { generatePath } from 'react-router-dom';\nimport { ActionCreator, AnyAction, Dispatch } from 'redux';\nimport { ThunkAction } from 'redux-thunk';\nimport { AppState } from '..';\nimport { RenewedSubscriptionKeys } from '../../dtos/subscription';\nimport { SubscriptionApiKey } from '../../models/enums';\nimport { Subscription } from '../../models/subscription';\nimport routes from '../../routes';\nimport { subscriptionsService } from '../../services/subscriptions/subscriptions-service';\nimport { PostSubscriptionsDtoIn } from '../../services/subscriptions/dtos/post-subscriptions/post-subscriptions-dto-in';\nimport { GetSubscriptionApiKeysDtoOut } from '../../services/subscriptions/dtos/get-subscription-api-keys/get-subscription-api-keys-dto-out';\n\nexport enum SubscriptionsActionTypes {\n CREATE_SUBSCRIPTION_SUCCESS = '[CREATE_SUBSCRIPTION_SUCCESS] Create a new subscription success',\n CREATE_SUBSCRIPTION_FAIL = '[CREATE_SUBSCRIPTION_FAIL] Create a new subscription failed',\n LOAD_BY_PARTNERID_SUCCESS = 'Load subscriptions by partner id success',\n SET_SUBSCRIPTIONS_LOADING = 'Subscriptions loading',\n SET_LOADING_SUBSCRIPTION_CREATE = '[SET_LOADING_SUBSCRIPTION_CREATE] create subscription loading',\n SET_PRIMARY_KEY_LOADING = 'Subscription primary key loading',\n SET_SECONDARY_KEY_LOADING = 'Subscription secondary key loading',\n GET_SUBSCRIPTION_KEYS_SUCCESS = '[SUBSCRIPTION]Get subscription keys success',\n GET_SUBSCRIPTION_KEYS_ERROR = '[SUBSCRIPTION]Get subscription keys error',\n SET_PRIMARY_KEY = 'Subscription primary key',\n SET_SECONDARY_KEY = 'Subscription secondary key',\n SET_SUBSCRIPTION = 'Set subscription',\n}\n\nexport const createSubscriptionStart: ActionCreator<\n ThunkAction, AppState, null, AnyAction>\n> = (data: {\n subscriptionDetails: PostSubscriptionsDtoIn;\n currentPartnerId: string;\n}) => {\n return async (dispatch: Dispatch) => {\n try {\n const responseData = await subscriptionsService.createSubscription(\n data.subscriptionDetails,\n data.currentPartnerId\n );\n dispatch(createSubscriptionSuccess(responseData));\n dispatch(\n push(\n `${generatePath(routes.checkout.base, {\n id: data.subscriptionDetails.productId,\n planId: data.subscriptionDetails.planId,\n })}${generatePath(routes.checkout.success, {\n subscriptionId: responseData.id,\n })}`\n )\n );\n } catch (error: any) {\n dispatch(createSubscriptionFail(error.response.statusText));\n dispatch(setSubscriptionCreateLoading(false));\n }\n };\n};\n\ninterface CreateSubscriptionSuccessAction {\n type: SubscriptionsActionTypes.CREATE_SUBSCRIPTION_SUCCESS;\n payload: Subscription;\n}\n\nconst createSubscriptionSuccess = (\n subscription: Subscription\n): CreateSubscriptionSuccessAction => ({\n type: SubscriptionsActionTypes.CREATE_SUBSCRIPTION_SUCCESS,\n payload: subscription,\n});\n\ninterface CreateSubscriptionFailAction {\n type: SubscriptionsActionTypes.CREATE_SUBSCRIPTION_FAIL;\n payload: string | undefined;\n}\n\nexport const createSubscriptionFail = (\n errorMessage: string | undefined\n): CreateSubscriptionFailAction => ({\n type: SubscriptionsActionTypes.CREATE_SUBSCRIPTION_FAIL,\n payload: errorMessage,\n});\n\ninterface LoadSubscriptionsByPartnerIdSuccessAction {\n type: SubscriptionsActionTypes.LOAD_BY_PARTNERID_SUCCESS;\n payload: Subscription[];\n}\n\nconst loadSubscriptionsByPartnerIdSuccess = (\n subscriptions: Subscription[]\n): LoadSubscriptionsByPartnerIdSuccessAction => ({\n type: SubscriptionsActionTypes.LOAD_BY_PARTNERID_SUCCESS,\n payload: subscriptions,\n});\n\nexport const loadSubscriptionsByPartnerIdStart: ActionCreator<\n ThunkAction, AppState, null, AnyAction>\n> = (partnerId: string) => {\n return async (dispatch: Dispatch) => {\n try {\n if (!!partnerId) {\n dispatch(setSubscriptionsLoading(true));\n const subscriptions =\n await subscriptionsService.getSubscriptionsByPartnerId(partnerId);\n dispatch(loadSubscriptionsByPartnerIdSuccess(subscriptions));\n } else {\n dispatch(loadSubscriptionsByPartnerIdSuccess([]));\n }\n } catch (err) {\n console.error(err);\n }\n };\n};\n\ninterface SetSubscriptionsLoadingAction {\n type: SubscriptionsActionTypes.SET_SUBSCRIPTIONS_LOADING;\n payload: boolean;\n}\n\nconst setSubscriptionsLoading = (\n loading: boolean\n): SetSubscriptionsLoadingAction => ({\n type: SubscriptionsActionTypes.SET_SUBSCRIPTIONS_LOADING,\n payload: loading,\n});\n\ninterface SetSubscriptionCreateLoadingAction {\n type: SubscriptionsActionTypes.SET_LOADING_SUBSCRIPTION_CREATE;\n payload: boolean;\n}\n\nexport const setSubscriptionCreateLoading = (\n loading: boolean\n): SetSubscriptionCreateLoadingAction => ({\n type: SubscriptionsActionTypes.SET_LOADING_SUBSCRIPTION_CREATE,\n payload: loading,\n});\n\ninterface SetSubscriptionPrimaryKeyLoadingAction {\n type: SubscriptionsActionTypes.SET_PRIMARY_KEY_LOADING;\n payload: { subscriptionId: string; loading: boolean };\n}\n\nconst setSubscriptionPrimaryKeyLoading = (\n subscriptionId: string,\n loading: boolean\n): SetSubscriptionPrimaryKeyLoadingAction => ({\n type: SubscriptionsActionTypes.SET_PRIMARY_KEY_LOADING,\n payload: {\n subscriptionId: subscriptionId,\n loading: loading,\n },\n});\n\ninterface SetSubscriptionPrimaryKeyAction {\n type: SubscriptionsActionTypes.SET_PRIMARY_KEY;\n payload: RenewedSubscriptionKeys;\n}\n\nconst setSubscriptionPrimaryKey = (\n renewedKeys: RenewedSubscriptionKeys\n): SetSubscriptionPrimaryKeyAction => ({\n type: SubscriptionsActionTypes.SET_PRIMARY_KEY,\n payload: renewedKeys,\n});\n\ninterface SetSubscriptionSecondaryKeyLoadingAction {\n type: SubscriptionsActionTypes.SET_SECONDARY_KEY_LOADING;\n payload: { subscriptionId: string; loading: boolean };\n}\n\nconst setSubscriptionSecondaryKeyLoading = (\n subscriptionId: string,\n loading: boolean\n): SetSubscriptionSecondaryKeyLoadingAction => ({\n type: SubscriptionsActionTypes.SET_SECONDARY_KEY_LOADING,\n payload: {\n subscriptionId: subscriptionId,\n loading: loading,\n },\n});\n\ninterface SetSubscriptionSecondaryKeyAction {\n type: SubscriptionsActionTypes.SET_SECONDARY_KEY;\n payload: RenewedSubscriptionKeys;\n}\n\nconst setSubscriptionSecondaryKey = (\n renewedKeys: RenewedSubscriptionKeys\n): SetSubscriptionSecondaryKeyAction => ({\n type: SubscriptionsActionTypes.SET_SECONDARY_KEY,\n payload: renewedKeys,\n});\n\nexport const renewSubscriptionKeysStart: ActionCreator<\n ThunkAction, AppState, null, AnyAction>\n> = (subscriptionId: string, requestedKey: string) => {\n return async (dispatch: Dispatch, getState) => {\n try {\n const currentPartnerId = getState().partner.currentPartner?.id;\n if (!currentPartnerId) {\n console.error('Current partner not present in state');\n return;\n }\n requestedKey === SubscriptionApiKey.PRIMARY\n ? dispatch(setSubscriptionPrimaryKeyLoading(subscriptionId, true))\n : dispatch(setSubscriptionSecondaryKeyLoading(subscriptionId, true));\n const newKeys = await subscriptionsService.renewSubscriptionKeys(\n currentPartnerId,\n subscriptionId,\n requestedKey\n );\n requestedKey === SubscriptionApiKey.PRIMARY\n ? dispatch(setSubscriptionPrimaryKey(newKeys))\n : dispatch(setSubscriptionSecondaryKey(newKeys));\n requestedKey === SubscriptionApiKey.PRIMARY\n ? dispatch(setSubscriptionPrimaryKeyLoading(subscriptionId, false))\n : dispatch(setSubscriptionSecondaryKeyLoading(subscriptionId, false));\n } catch (err) {\n console.error(err);\n requestedKey === SubscriptionApiKey.PRIMARY\n ? dispatch(setSubscriptionPrimaryKeyLoading(subscriptionId, false))\n : dispatch(setSubscriptionSecondaryKeyLoading(subscriptionId, false));\n }\n };\n};\n\ninterface GetSubscriptionKeysSuccessAction {\n type: SubscriptionsActionTypes.GET_SUBSCRIPTION_KEYS_SUCCESS;\n payload: GetSubscriptionApiKeysDtoOut;\n}\n\nconst getSubscriptionKeysSuccess = (\n response: GetSubscriptionApiKeysDtoOut\n): GetSubscriptionKeysSuccessAction => ({\n type: SubscriptionsActionTypes.GET_SUBSCRIPTION_KEYS_SUCCESS,\n payload: response,\n});\n\ninterface GetSubscriptionKeysErrorAction {\n type: SubscriptionsActionTypes.GET_SUBSCRIPTION_KEYS_ERROR;\n payload: { subscriptionId: string; isError: boolean };\n}\n\nconst getSubscriptionKeysError = (\n subscriptionId: string,\n isError: boolean\n): GetSubscriptionKeysErrorAction => ({\n type: SubscriptionsActionTypes.GET_SUBSCRIPTION_KEYS_ERROR,\n payload: {\n subscriptionId: subscriptionId,\n isError: isError,\n },\n});\n\nexport const getSubscriptionKeysStart: ActionCreator<\n ThunkAction, AppState, null, AnyAction>\n> = (subscriptionId: string) => {\n return async (dispatch: Dispatch, getState) => {\n try {\n const currentPartnerId = getState().partner.currentPartner?.id;\n if (!currentPartnerId) {\n console.error('Current partner not present in state');\n return;\n }\n\n dispatch(setSubscriptionPrimaryKeyLoading(subscriptionId, true));\n dispatch(setSubscriptionSecondaryKeyLoading(subscriptionId, true));\n dispatch(getSubscriptionKeysError(subscriptionId, false));\n const getSubscriptionApiKeysDtoOut =\n await subscriptionsService.getSubscriptionKeys(\n currentPartnerId,\n subscriptionId\n );\n dispatch(getSubscriptionKeysSuccess(getSubscriptionApiKeysDtoOut));\n dispatch(setSubscriptionPrimaryKeyLoading(subscriptionId, false));\n dispatch(setSubscriptionSecondaryKeyLoading(subscriptionId, false));\n } catch (err) {\n console.error(err);\n dispatch(setSubscriptionPrimaryKeyLoading(subscriptionId, false));\n dispatch(setSubscriptionSecondaryKeyLoading(subscriptionId, false));\n dispatch(getSubscriptionKeysError(subscriptionId, true));\n }\n };\n};\n\ninterface SetSubscriptionAction {\n type: SubscriptionsActionTypes.SET_SUBSCRIPTION;\n payload: Subscription;\n}\n\nexport const setSubscription = (\n subscription: Subscription\n): SetSubscriptionAction => ({\n type: SubscriptionsActionTypes.SET_SUBSCRIPTION,\n payload: subscription,\n});\n\nexport type SubscriptionsActions =\n | CreateSubscriptionSuccessAction\n | CreateSubscriptionFailAction\n | LoadSubscriptionsByPartnerIdSuccessAction\n | SetSubscriptionsLoadingAction\n | SetSubscriptionCreateLoadingAction\n | SetSubscriptionPrimaryKeyLoadingAction\n | SetSubscriptionSecondaryKeyLoadingAction\n | SetSubscriptionPrimaryKeyAction\n | SetSubscriptionSecondaryKeyAction\n | GetSubscriptionKeysSuccessAction\n | GetSubscriptionKeysErrorAction\n | SetSubscriptionAction;\n","import { User } from './user';\nimport { MemberStatus, AvailabilityStatus } from './enums';\n\nexport default interface Partner {\n id: string;\n companyName: string;\n displayName?: string;\n billingAddress: string;\n billingCity: string;\n billingPostalCode: string;\n billingCountry: string;\n homePage?: string;\n taxNumber?: string;\n vatNumber?: string;\n contactName: string;\n contactEmail: string;\n members?: PartnerMember[];\n applications?: PartnerApplication[];\n partnerCreatedInAPIM?: boolean;\n partnerCreatedInStripe?: boolean;\n availabilityStatus: AvailabilityStatus;\n hasSubscriptions: boolean;\n hasServices: boolean;\n consumerFrameContractSigned: boolean;\n providerFrameContractSigned: boolean;\n shortDescription: string;\n}\n\nexport interface PartnerAbstract {\n companyName: string;\n displayName?: string;\n}\n\nexport interface NewPartnerMember {\n email: string;\n roles: RoleConfig[];\n}\n\nexport interface PartnerMember {\n user: User;\n status: MemberStatus;\n roles: RoleConfig[];\n}\n\nexport interface RoleConfig {\n role: Role;\n scope: Scope;\n\n /**\n * The id of the entity (e.g. product ID)\n */\n entityIds?: string[];\n}\n\nexport enum Role {\n OWNER = 'owner',\n MEMBER = 'member',\n MAINTAINER = 'maintainer',\n}\n\nexport enum Scope {\n PARTNER = 'partner',\n PRODUCT = 'product',\n}\n\nexport interface UserPartner {\n id: string;\n companyName: string;\n displayName?: string;\n roles: RoleConfig[];\n partnerCreatedInAPIM: boolean | undefined;\n partnerCreatedInStripe: boolean | undefined;\n hasSubscriptions: boolean;\n hasServices: boolean;\n availabilityStatus: AvailabilityStatus;\n consumerFrameContractSigned: boolean;\n providerFrameContractSigned: boolean;\n shortDescription: string;\n}\n\nexport interface PartnerApplication {\n id: string;\n applicationId: string;\n secretHint: string;\n displayName: string;\n roles: RoleConfig[];\n}\n\nexport interface NewPartnerApplication {\n displayName: string;\n roles: RoleConfig[];\n}\n","import { ActionCreator, Dispatch } from 'redux';\nimport { ThunkAction } from 'redux-thunk';\nimport { AppState } from '..';\nimport { ProductStatus } from '../../models/enums';\nimport { GetPartnersProductsAllDtoOut } from '../../services/partners-products/dtos/get-partners-products-all/get-partners-products-all-dto-out';\nimport { dashboardProductsService } from '../../services/partners-products/partners-products-service';\nimport { ProductsState } from '../reducers/productsReducer';\n\nexport enum DashboardProductsActionTypes {\n LOAD_ALL_DASHBOARD_PRODUCTS = '[DashboardProducts] Load all dashboard products',\n LOAD_ALL_DASHBOARD_PRODUCTS_SUCCESS = '[DashboardProducts] Load all dashboard products success',\n LOAD_ALL_DASHBOARD_PRODUCTS_FAIL = '[DashboardProducts] Load all dashboard products fail',\n SET_DASHBOARD_PRODUCTS_LOADING = '[DashboardProducts] Set dashboard products loading',\n SET_PRODUCT_STATUS = '[DashboardProducts] Set dashboard product status',\n DELETE_DASHBOARD_PRODUCT_SUCCESS = 'Delete a product success',\n CLEAR_DASHBOARD_PRODUCTS = 'Clear current dashboard products',\n}\n\ninterface LoadAllDashboardProductsAction {\n type: typeof DashboardProductsActionTypes.LOAD_ALL_DASHBOARD_PRODUCTS;\n}\n\nexport const loadAllDashboardProducts: ActionCreator<\n ThunkAction, AppState, null, LoadAllDashboardProductsAction>\n> = () => {\n return async (dispatch: Dispatch, getState) => {\n try {\n const currentPartner = getState().partner.currentPartner;\n if (!currentPartner) {\n dispatch(loadAllDashboardProductsFail('Current partner not loaded'));\n return;\n }\n dispatch(setDashboardProductsLoading(true));\n\n const products = await dashboardProductsService.getAllDashboardProducts(\n currentPartner.id\n );\n\n dispatch(loadAllDashboardProductsSuccess(products));\n } catch (err) {\n dispatch(loadAllDashboardProductsFail(err));\n }\n };\n};\n\ninterface LoadAllDashboardProductsSuccessAction {\n type: typeof DashboardProductsActionTypes.LOAD_ALL_DASHBOARD_PRODUCTS_SUCCESS;\n payload: GetPartnersProductsAllDtoOut[];\n}\n\nconst loadAllDashboardProductsSuccess = (\n payload: GetPartnersProductsAllDtoOut[]\n): LoadAllDashboardProductsSuccessAction => ({\n type: DashboardProductsActionTypes.LOAD_ALL_DASHBOARD_PRODUCTS_SUCCESS,\n payload,\n});\n\ninterface LoadAllDashboardProductsFailAction {\n type: typeof DashboardProductsActionTypes.LOAD_ALL_DASHBOARD_PRODUCTS_FAIL;\n payload: any;\n}\n\nconst loadAllDashboardProductsFail = (\n payload: any\n): LoadAllDashboardProductsFailAction => ({\n type: DashboardProductsActionTypes.LOAD_ALL_DASHBOARD_PRODUCTS_FAIL,\n payload,\n});\n\ninterface SetDashboardProductsLoadingAction {\n type: typeof DashboardProductsActionTypes.SET_DASHBOARD_PRODUCTS_LOADING;\n payload: boolean;\n}\n\nconst setDashboardProductsLoading = (\n payload: boolean\n): SetDashboardProductsLoadingAction => ({\n type: DashboardProductsActionTypes.SET_DASHBOARD_PRODUCTS_LOADING,\n payload,\n});\n\ninterface SetProductStatusAction {\n type: typeof DashboardProductsActionTypes.SET_PRODUCT_STATUS;\n payload: { productId: string; status: ProductStatus };\n}\n\nexport const setProductStatus = (payload: {\n productId: string;\n status: ProductStatus;\n}): SetProductStatusAction => ({\n type: DashboardProductsActionTypes.SET_PRODUCT_STATUS,\n payload,\n});\n\ninterface DeleteProductSuccessAction {\n type: typeof DashboardProductsActionTypes.DELETE_DASHBOARD_PRODUCT_SUCCESS;\n payload: string;\n}\n\nconst deleteProductSuccess = (\n productId: string\n): DeleteProductSuccessAction => ({\n type: DashboardProductsActionTypes.DELETE_DASHBOARD_PRODUCT_SUCCESS,\n payload: productId,\n});\n\nexport const deleteDashboardProduct: ActionCreator<\n ThunkAction, ProductsState, null, DeleteProductSuccessAction>\n> = (productId: string, partnerId: string) => {\n return async (dispatch: Dispatch) => {\n try {\n const deletedProduct = await dashboardProductsService.deleteProduct(\n productId,\n partnerId\n );\n dispatch(deleteProductSuccess(deletedProduct.id));\n } catch (err) {}\n };\n};\n\ninterface ClearDashboardProductsAction {\n type: typeof DashboardProductsActionTypes.CLEAR_DASHBOARD_PRODUCTS;\n payload: boolean;\n}\nexport const clearDashboardProducts = (dashboardProductsLoading: boolean): ClearDashboardProductsAction => ({\n type: DashboardProductsActionTypes.CLEAR_DASHBOARD_PRODUCTS,\n payload: dashboardProductsLoading\n});\n\nexport type DashboardProductsActions =\n | LoadAllDashboardProductsAction\n | LoadAllDashboardProductsSuccessAction\n | LoadAllDashboardProductsFailAction\n | SetDashboardProductsLoadingAction\n | SetProductStatusAction\n | DeleteProductSuccessAction\n | ClearDashboardProductsAction;\n","import { AvailabilityStatus } from '../../../../models/enums';\nimport Partner, { PartnerMember } from '../../../../models/partner';\n\nexport class PostPartnerDtoOut {\n id: string;\n companyName: string;\n displayName?: string;\n billingAddress: string;\n billingCity: string;\n billingPostalCode: string;\n billingCountry: string;\n homePage?: string;\n taxNumber?: string;\n vatNumber?: string;\n contactName: string;\n contactEmail: string;\n members: PartnerMember[];\n partnerCreatedInAPIM?: boolean;\n partnerCreatedInStripe?: boolean;\n availabilityStatus: AvailabilityStatus;\n hasSubscriptions: boolean;\n hasServices: boolean;\n consumerFrameContractSigned: boolean;\n providerFrameContractSigned: boolean;\n shortDescription: string;\n\n static fromDto(postPartnersDtoOut: PostPartnerDtoOut): Partner {\n return {\n ...postPartnersDtoOut,\n };\n }\n}\n","import { AvailabilityStatus } from '../../../../models/enums';\nimport Partner, { PartnerMember } from '../../../../models/partner';\n\nexport class GetPartnerByIdDtoOut {\n id: string;\n companyName: string;\n displayName?: string;\n billingAddress: string;\n billingCity: string;\n billingPostalCode: string;\n billingCountry: string;\n homePage?: string;\n taxNumber?: string;\n vatNumber?: string;\n contactName: string;\n contactEmail: string;\n members: PartnerMember[];\n partnerCreatedInAPIM?: boolean;\n partnerCreatedInStripe?: boolean;\n availabilityStatus: AvailabilityStatus;\n hasSubscriptions: boolean;\n hasServices: boolean;\n consumerFrameContractSigned: boolean;\n providerFrameContractSigned: boolean;\n shortDescription: string;\n _etag: string;\n\n static fromDto(getPartnersByIdDtoOut: GetPartnerByIdDtoOut): Partner {\n return {\n ...getPartnersByIdDtoOut,\n };\n }\n}\n","import { AvailabilityStatus } from '../../../../models/enums';\nimport Partner, { PartnerMember } from '../../../../models/partner';\n\nexport default class PutPartnerDtoOut {\n id: string;\n companyName: string;\n displayName?: string;\n billingAddress: string;\n billingCity: string;\n billingPostalCode: string;\n billingCountry: string;\n homePage?: string;\n taxNumber?: string;\n vatNumber?: string;\n contactName: string;\n contactEmail: string;\n members: PartnerMember[];\n partnerCreatedInAPIM?: boolean;\n availabilityStatus: AvailabilityStatus;\n hasSubscriptions: boolean;\n hasServices: boolean;\n consumerFrameContractSigned: boolean;\n providerFrameContractSigned: boolean;\n shortDescription: string;\n\n static fromDto(putPartnersDtoOut: PutPartnerDtoOut): Partner {\n return {\n ...putPartnersDtoOut,\n };\n }\n}\n","import { PartnerFields } from '../../../../dynamic-pages/dashboard/partner-details/PartnerForm';\nimport { AttachmentDto } from '../../../../dtos/attachment';\nimport { PartnerMember } from '../../../../models/partner';\n\nexport default class PutPartnerDtoIn {\n companyName: string;\n displayName?: string;\n billingAddress: string;\n billingCity: string;\n billingPostalCode: string;\n billingCountry: string;\n homePage?: string;\n taxNumber?: string;\n vatNumber?: string;\n contactName: string;\n contactEmail: string;\n members?: PartnerMember[];\n logo: AttachmentDto;\n shortDescription: string;\n\n static toDto(\n data: PartnerFields,\n contactName: string,\n contactEmail: string,\n logo: AttachmentDto\n ): PutPartnerDtoIn {\n return {\n ...data,\n contactName: contactName,\n contactEmail: contactEmail,\n logo: logo,\n };\n }\n}\n","import { AvailabilityStatus } from '../../../../models/enums';\nimport { RoleConfig, UserPartner } from '../../../../models/partner';\n\nexport class GetPartnersUsersDtoOut {\n id: string;\n companyName: string;\n displayName?: string;\n roles: RoleConfig[];\n partnerCreatedInAPIM: boolean | undefined;\n partnerCreatedInStripe: boolean | undefined;\n hasSubscriptions: boolean;\n hasServices: boolean;\n availabilityStatus: AvailabilityStatus;\n consumerFrameContractSigned: boolean;\n providerFrameContractSigned: boolean;\n shortDescription: string;\n\n static fromDto(getPartnersDtoOut: GetPartnersUsersDtoOut): UserPartner {\n return {\n ...getPartnersDtoOut,\n };\n }\n}\n","import { PartnerFields } from '../../../../dynamic-pages/dashboard/partner-details/PartnerForm';\nimport { AttachmentDto } from '../../../../dtos/attachment';\n\nexport default class PostPartnerDtoIn {\n companyName: string;\n displayName?: string;\n billingAddress: string;\n billingCity: string;\n billingPostalCode: string;\n billingCountry: string;\n homePage?: string;\n taxNumber?: string;\n vatNumber?: string;\n contactName: string;\n contactEmail: string;\n logo: AttachmentDto;\n shortDescription: string;\n\n static toDto(\n partnerFields: PartnerFields,\n contactName: string,\n contactEmail: string,\n logo: AttachmentDto\n ): PostPartnerDtoIn {\n return {\n ...partnerFields,\n contactName,\n contactEmail,\n logo,\n };\n }\n}\n","import axios from '../httpClient';\nimport countryRegionData, { Country } from 'country-region-data';\nimport Partner, {\n RoleConfig,\n NewPartnerApplication,\n NewPartnerMember,\n PartnerMember,\n Role,\n Scope,\n UserPartner,\n} from '../../models/partner';\nimport {\n authScopes,\n getCurrentAccount,\n acquireTokenSilentOrRefreshToken,\n} from '../auth';\nimport { PostPartnerDtoOut } from './dtos/post-partner/post-partners-dto-out';\nimport { GetPartnerByIdDtoOut } from './dtos/get-partner-by-id/get-partner-by-id-dto-out';\nimport PutPartnerDtoOut from './dtos/put-partner/put-partner-dto-out';\nimport PutPartnerDtoIn from './dtos/put-partner/put-partner-dto-in';\nimport { GetPartnersUsersDtoOut } from './dtos/get-partners-users/get-partners-users-dto-out';\nimport PostPartnerDtoIn from './dtos/post-partner/post-partner-dto-in';\nimport { PartnerFields } from '../../dynamic-pages/dashboard/partner-details/PartnerForm';\nimport { convertLogo } from '../../util/util';\nimport { SecurityLog } from '../../models/security-log';\nimport { GetPartnerSecurityLogs } from './dtos/get-partner-security-logs/get-partner-by-id-dto-out';\nimport { appConfiguration } from '../../configuration';\nimport { MemberStatus } from '../../models/enums';\nimport { PostPartnerApplicationDtoOut } from './dtos/post-partner-application/post-partner-application-dto-out';\n\nclass PartnerService {\n private baseUrl: string;\n private supportedCountries = [\n 'DE',\n 'AT',\n 'RO',\n 'CH',\n 'US',\n 'GB',\n 'BE',\n 'FR',\n 'ES',\n 'SE',\n ];\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl;\n }\n\n async createPartner(\n partnerFields: PartnerFields,\n contactName: string,\n contactEmail: string\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n const postPartnerDtoIn = PostPartnerDtoIn.toDto(\n partnerFields,\n contactName,\n contactEmail,\n await convertLogo(partnerFields.logo as FileList)\n );\n\n return PostPartnerDtoOut.fromDto(\n (\n await axios.post(`${this.baseUrl}/partners`, postPartnerDtoIn, {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n })\n ).data\n );\n }\n\n async updatePartner(\n partnerId: string | undefined,\n partnerFields: PartnerFields,\n contactName: string,\n contactEmail: string\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n const putPartnersDtoIn = PutPartnerDtoIn.toDto(\n partnerFields,\n contactName,\n contactEmail,\n await convertLogo(partnerFields.logo as FileList)\n );\n\n return PutPartnerDtoOut.fromDto(\n (\n await axios.put(\n `${this.baseUrl}/partners/${partnerId}`,\n putPartnersDtoIn,\n {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n }\n )\n ).data\n );\n }\n\n async getUserPartners(): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return (\n await axios.get(`${this.baseUrl}/partners`, {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n })\n ).data.map(GetPartnersUsersDtoOut.fromDto);\n }\n\n async getPartnerById(partnerId: string): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return GetPartnerByIdDtoOut.fromDto(\n (\n await axios.get(`${this.baseUrl}/partners/${partnerId}`, {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n })\n ).data\n );\n }\n\n async addNewMember(\n partnerId: string,\n member: NewPartnerMember\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return (\n await axios.post(\n `${this.baseUrl}/partners/${partnerId}/members`,\n member,\n {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n }\n )\n ).data;\n }\n\n async removeMember(\n partnerId: string,\n memberId: string,\n withdrawEmail: string | undefined\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n return (\n await axios.delete(\n `${this.baseUrl}/partners/${partnerId}/members/${memberId || ''}`,\n {\n headers: {\n Authorization: `Bearer ${authResult.idToken}`,\n 'mp-withdraw-email': withdrawEmail,\n },\n }\n )\n ).data;\n }\n\n async updateMember(\n partnerId: string,\n member: PartnerMember\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return (\n await axios.put(\n `${this.baseUrl}/partners/${partnerId}/members/${member.user.id}`,\n member.roles,\n {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n }\n )\n ).data;\n }\n\n async addNewApplication(\n partnerId: string,\n application: NewPartnerApplication\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return (\n await axios.post(\n `${this.baseUrl}/partners/${partnerId}/applications`,\n application,\n { headers: { Authorization: `Bearer ${authResult.idToken}` } }\n )\n ).data;\n }\n\n async getPartnerSecurityLogs(partnerId: string): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return (\n (\n await axios.get(`${this.baseUrl}/partners/security-logs/${partnerId}`, {\n headers: { Authorization: `Bearer ${authResult.idToken}` },\n })\n ).data as GetPartnerSecurityLogs\n ).securityLogs;\n }\n\n getSupportedCountries(): Country[] {\n return countryRegionData.filter((c) =>\n this.supportedCountries.includes(c.countryShortCode)\n );\n }\n\n getPartnerRoles(role: Role, productIds?: string[]): RoleConfig[] {\n switch (role) {\n case Role.MEMBER:\n case Role.OWNER:\n return [{ role: role, scope: Scope.PARTNER }];\n case Role.MAINTAINER:\n return [\n {\n role: role,\n scope: Scope.PRODUCT,\n entityIds: productIds,\n },\n ];\n }\n }\n\n async processInvitation(\n partnerId: string,\n email: string\n ): Promise {\n const authResult = await acquireTokenSilentOrRefreshToken({\n scopes: authScopes,\n account: getCurrentAccount(),\n });\n\n return (\n await axios.post(\n `${this.baseUrl}/partners/${partnerId}/members/invitation`,\n {\n email: email,\n },\n {\n headers: {\n Authorization: `Bearer ${authResult.idToken}`,\n email: email,\n },\n }\n )\n ).data;\n }\n}\n\nexport const partnerService = new PartnerService(\n appConfiguration()?.coreApiUrl ?? ''\n);\n","import { Theme } from '@mui/material/styles';\nimport createStyles from '@mui/styles/createStyles';\nimport makeStyles from '@mui/styles/makeStyles';\nimport { Distances } from '../../AppTheme';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n button: {\n transition: 'all 0.10s',\n padding: `8px 25px`,\n letterSpacing: '0.5px',\n textTransform: 'none',\n color: theme.palette.typography.main,\n lineHeight: '0px',\n },\n primary: {\n width: Distances.BUTTON_LENGTH,\n height: '40px',\n borderRadius: '20px',\n lineHeight: '24px',\n backgroundColor: theme.palette.yellow.main,\n '&:hover': {\n backgroundColor: theme.palette.yellow.main,\n boxShadow: '0px 4px 9px 0px rgba(0, 0, 0, 0.3)',\n },\n },\n secondary: {\n borderRadius: '20px',\n backgroundColor: theme.palette.white.main,\n border: '1px solid',\n borderColor: theme.palette.typography.main,\n '&:hover': {\n backgroundColor: theme.palette.white.main,\n boxShadow: '0px 4px 9px 0px rgba(0, 0, 0, 0.3)',\n },\n },\n secondarySmall: {\n width: '103px',\n height: '36px',\n },\n secondaryBig: {\n width: Distances.BUTTON_LENGTH,\n height: '40px',\n },\n tertiary: {\n width: '103px',\n height: '36px',\n borderRadius: '20px',\n backgroundColor: 'transparent',\n },\n filterAndClose: {\n width: '81px',\n height: '30px',\n borderRadius: '20px',\n backgroundColor: theme.palette.yellow.main,\n '&:hover': {\n backgroundColor: theme.palette.yellow.main,\n boxShadow: '0px 4px 9px 0px rgba(0, 0, 0, 0.3)',\n },\n minWidth: 'max-content',\n },\n filterOption: {},\n closeIcon: {\n fontSize: '13px !important',\n lineHeight: '13px',\n },\n contactMenu: {\n width: '150px',\n height: '40px',\n borderRadius: '5px',\n padding: '10px',\n backgroundColor: theme.palette.lightRed.main,\n color: theme.palette.white.main,\n '&:hover': {\n backgroundColor: theme.palette.lightRed.main,\n boxShadow: '0px 4px 9px 0px rgba(0, 0, 0, 0.3)',\n },\n },\n contactForm: {\n width: '100%',\n height: '50px',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n borderRadius: '5px',\n padding: '9px',\n\n '&:hover': {\n boxShadow: '0px 4px 9px 0px rgba(0, 0, 0, 0.3)',\n },\n },\n disabled: {\n filter: 'grayscale(50%)',\n borderColor: theme.palette.border.main,\n },\n disabledArrow: {\n filter: 'opacity(0.5)',\n },\n enabledArrow: {\n filter: 'opacity(1.0)',\n },\n icon: {\n display: 'flex',\n justifyContent: 'center',\n height: '13px',\n },\n downwardsArrowIcon: {\n height: '7px !important',\n },\n noBorderRadius: {\n borderRadius: '0 !important',\n },\n selector: {\n height: '27px !important',\n },\n close: {\n lineHeight: '24px',\n },\n selectorTypography: {\n lineHeight: '27px !important'\n }\n })\n);\n\nexport default useStyles;\n","import React from 'react';\nimport { clsx } from 'clsx';\nimport { Link } from 'react-router-dom';\nimport { Button, ButtonProps, Icon, Typography } from '@mui/material';\nimport { MPButton2BaseProps } from './MPButtonBase';\nimport useStyles from './MPButtonBase2.styles';\n\ntype CustomButtonProps = Omit;\n\nconst MPButton2: React.FC = ({\n styleVariant,\n customClasses,\n children,\n disabled,\n square,\n navigate,\n ...buttonProps\n}) => {\n const classes = useStyles();\n\n return (\n \n );\n};\n\nexport default MPButton2;\n","import { UserPartner } from '../models/partner';\n\nconst CURRENT_PARTNER = 'currentPartner';\n\nclass LocalService {\n setCurrentPartner(partner: UserPartner) {\n localStorage.setItem(CURRENT_PARTNER, JSON.stringify(partner));\n }\n getCurrentPartner(): UserPartner | undefined {\n const partnerJson = localStorage.getItem(CURRENT_PARTNER);\n if (!partnerJson) {\n return undefined;\n }\n\n return JSON.parse(partnerJson);\n }\n clearCurrentPartner() {\n localStorage.removeItem(CURRENT_PARTNER);\n }\n}\n\nexport const localService = new LocalService();\n","/* eslint-disable import/no-named-as-default*/\nimport i18n from 'i18next';\nimport Backend from 'i18next-http-backend';\nimport LanguageDetector, {\n DetectorOptions,\n} from 'i18next-browser-languagedetector';\nimport { initReactI18next } from 'react-i18next';\nimport { appConfiguration } from './configuration';\n\nexport const supportedLngs = [\n { key: 'de', text: 'Deutsch' },\n { key: 'en', text: 'English' },\n];\n\nconst detectorOptions: DetectorOptions = {\n order: [\n 'path',\n 'querystring',\n 'cookie',\n 'localStorage',\n 'sessionStorage',\n 'subdomain',\n ],\n lookupLocalStorage: 'i18nextLng',\n caches: ['localStorage'],\n};\n\ni18n\n .use(Backend)\n .use(LanguageDetector)\n .use(initReactI18next)\n .init({\n fallbackLng: 'de',\n supportedLngs: supportedLngs.map((l) => l.key),\n debug: process.env.NODE_ENV !== 'production',\n interpolation: {\n escapeValue: false,\n },\n react: {\n transEmptyNodeValue: '',\n transSupportBasicHtmlNodes: true,\n transKeepBasicHtmlNodesFor: ['br', 'strong', 'i'],\n },\n detection: detectorOptions,\n backend: {\n loadPath: appConfiguration()?.local?.localePath\n ? `env/${\n appConfiguration()?.local?.localePath\n }/locales/{{lng}}/{{ns}}.json`\n : '/locales/{{lng}}/{{ns}}.json',\n },\n })\n .catch((err) => {\n console.log('error at i18n.init: ', err);\n });\nexport default i18n;\n","export const convertUTCUnixTimestampToDate = (timestamp: number): string => {\n return Intl.DateTimeFormat('default', {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n }).format(timestamp * 1000 - new Date().getTimezoneOffset() * 60_000);\n};\n\nexport const convertUnixTimestampToDateAndTime = (\n timestamp: number\n): string => {\n return Intl.DateTimeFormat('default', {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n }).format(timestamp);\n};\n\nexport const convertUnixTimestampToTime = (timestamp: number): string => {\n return Intl.DateTimeFormat('default', {\n hour: 'numeric',\n minute: 'numeric',\n }).format(timestamp);\n};\n\nexport const convertDateToUnixTimestamp = (date: Date): number => {\n return date.getTime() / 1000;\n};\n\nexport const checkIfNotificationWasCreatedToday = (\n createdAt: number\n): boolean => {\n const today = new Date();\n const notificationCreationDay = new Date(createdAt);\n return (\n today.setHours(0, 0, 0, 0) === notificationCreationDay.setHours(0, 0, 0, 0)\n );\n};\n\nexport const numberOfDaysBetweenTimestamps = (\n timestamp1: number,\n timestamp2: number\n): number => {\n const differenceInMilliseconds = timestamp1 - timestamp2;\n const differenceInDays = Math.floor(\n differenceInMilliseconds / (1000 * 60 * 60 * 24)\n );\n\n return differenceInDays;\n};\n"],"sourceRoot":""}