{"version":3,"sources":["redux/productReducer.js","redux/search2Reducer.js","redux/thunk/materialThunk.js","redux/adapter/productAdapter.js","styles.js","redux/customerOrderReducer.js","redux/hook/errorHooks.js","redux/localStorage.js","redux/middleware/api.js","redux/materialReducer.js","redux/thunk/newsArticleThunk.js","redux/newsArticleReducer.js","redux/adapter/modelAdapter.js","redux/thunk/modelThunk.js","redux/modelSlice.js","redux/thunk/collectionThunk.js","redux/collectionReducer.js","redux/rootReducer.js","redux/store.js","App.js","index.js","lib/helper/brandHelper.js","lib/helper/newsHelper.js","redux/adapter/newsArticleAdapter.js","redux/thunk/productThunk.js","lib/helper/searchHelper.js","redux/services/broditWebApi.js","redux/cartSlice.js","redux/api.js","components/CompareProducts/helperFunctions.js","redux/priceSlice.js","redux/cookieStorage.js","redux/favoriteSlice.js","redux/services/cartApi.js","lib/helper/modelHelper.js","lib/Localization.js","redux/services/priceApi.js","redux/services/productInfoApi.js","lib/helper/dynamicContentHelper.js","redux/services/contentApi.js","redux/thunk/customerOrderThunk.js","redux/services/favoriteApi.js","redux/adapter/materialAdapter.js","lib/hooks/languageHooks.js","redux/adapter/priceAdapter.js","theme.js","lib/helper/viewportHelper.js","redux/hook/userHooks.js","redux/userMessageSlice.js","redux/searchReducer.js","redux/userSlice.js","redux/compareProductsReducer.js","redux/pageReducer.js","redux/settingsReducer.js","redux/monitorSlice.js"],"names":["slice","createSlice","name","initialState","productAdapter","getInitialState","modtekProducts","relatedProducts","lastProductFetch","lastFetchItemCount","lastFetchProperties","brands","productNames","loading","pendingRequests","reducers","reset","removeAll","deleteSearchResult","state","extraReducers","builder","addCase","requestProduct","pending","Boolean","fulfilled","action","_action$payload","pagedList","payload","response","list","length","products","prepareProducts","meta","arg","lang","addOne","rejected","requestProducts","_action$payload2","key","addMany","requestFilteredProducts","_action$payload3","map","x","originalId","pagingHeader","totalItems","names","actions","clearSearchResult","dispatch","search2Slice","setSearchQuery2","_ref","type","value","clearFilter","searchQueries","filterFaultyValues","updateSearchQuery2","_ref2","newValue","clearSearchQuery2","_ref3","exclude","excludedSearchQueries","Object","entries","reduce","prev","_ref4","includes","requestMaterial","createAsyncThunk","async","id","params","a","axios","get","internalLangConvert","data","fetchMaterial","condition","getState","selectById","createEntityAdapter","selectId","product","sortComparer","b","sortOrder","modtekProductSelectors","getSelectors","relatedProductSelectors","selectAll","selectAllModtekProducts","selectModtekProductById","selectAllRelatedProducts","selectRelatedProductById","productSelectors","makeStyles","root","flex","display","flexDirection","alignItems","homePage","width","errors","clearErrors","requestCustomerOrders","push","requestCustomerOrder","useErrors","priceErrors","useSelector","price","customerOrderErrors","customerOrder","useEffect","reducersToSave","api","next","url","method","onStart","onSuccess","onError","request","error","message","materialAdapter","requestNewsArticleById","fetchNewsArticleById","some","requestNewsArticles","limit","group","includeFutureNews","groupParam","fetchNewsArticles","newsArticleAdapter","article","modelAdapter","model","modelNameCompare","modelSelectors","requestModel","fetchModel","requestModelsByBrand","brandId","language","steering","arguments","undefined","restoredBrandId","restoreNameForBrandOther","steeringParams","fetchModelsForBrand","modelSlice","lastModelFetch","requestCollectionsForBrand","fetchCollectionsForModel","rootReducer","combineReducers","cart","cartReducer","user","userReducer","productReducer","material","materialReducer","monitor","monitorReducer","settings","settingsReducer","priceReducer","customerOrderReducer","newsArticle","newsArticleReducer","collection","collectionReducer","page","pageSlice","search","searchReducer","search2","search2Reducer","userMessage","userMessageReducer","favorite","favoriteReducer","compareProduct","compareProductsReducer","broditWebApi","reducerPath","reducer","contentApi","cartApi","favoriteApi","priceApi","productInfoApi","persistConfig","storage","whitelist","persistedReducer","persistReducer","store","configureStore","preloadedState","loadReducers","serializedReducers","localStorage","getItem","JSON","parse","err","console","warn","middleware","getDefaultMiddleware","serializableCheck","concat","thunk","persistor","persistStore","setupListeners","CompareOverview","lazy","CompareProducts","CustomerOrderInfo","CustomerOrders","DynamicContentPage","ErrorMessage","FavoriteProductsPage","FileDownload","FilterProducts","FlashMessage","Footer","Home","LandingPageMetaDescription","MessageNotification","Navbar","NewsLetter","NewsListPage","NewsMetaDescription","NewsPage","NotFound","Order","OrderUpload","Page","ResetPassword","SignIn","StateHandler","User","VehicleNewsListPage","PrivacyPolicy","ContactPage","About","ProclipAndHolders","CategoriesPage","ProductDevelopment","RetailersPage","DesktopProductInfoNew","QuickShop","ErrorPage","CookieManager","then","module","default","AboutPageMetaDescription","NoIndexMetaData","ProductDevelopmentMetaDescription","ProclipAndHoldersMetaDescription","CategoriesMetaDescription","ProclipMetaDescription","SignInMetaDescription","RouteChangeTracker","App","_location$pathname$ma","classes","useStyles","useLanguage","isAuthorized","useIsUserAuthorized","useDispatch","isTablet","useMediaQuery","theme","breakpoints","down","tabletBreakpoint","logFrontendError","useLogFrontendErrorMutation","location","useLocation","Localization","setLanguage","subscribe","forEach","stringify","setItem","saveReducers","_jsx","ErrorBoundary","FallbackComponent","info","stack","componentStack","children","showManageButton","privacyPolicyUrl","translations","title","cmtitle","cmmessage","buttonText","cmbuttonText","declineButtonText","cmdeclineButtonText","manageButtonText","cmmanageButtonText","privacyPolicyText","cmprivacyPolicyText","manageTitle","cmmanageTitle","manageMessage","cmmanageMessage","manageEssentialTitle","cmmanageEssentialTitle","manageEssentialSubtitle","cmmanageEssentialSubtitle","manageEssentialStatus","cmmanageEssentialStatus","manageEssentialStatusButtonText","cmmanageEssentialStatusButtonText","manageAnalyticsTitle","cmmanageAnalyticsTitle","manageAnalyticsSubtitle","cmmanageAnalyticsSubtitle","manageSocialTitle","cmmanageSocialTitle","manageSocialSubtitle","cmmanageSocialSubtitle","manageAdvertTitle","cmmanageAdvertTitle","manageAdvertSubtitle","cmmanageAdvertSubtitle","manageCookiesStatus","cmmanageCookiesStatus","manageCookiesStatusConsented","cmmanageCookiesStatusConsented","manageCookiesStatusDeclined","cmmanageCookiesStatusDeclined","manageCancelButtonText","cmmanageCancelButtonText","manageSaveButtonText","cmmanageSaveButtonText","StyledEngineProvider","injectFirst","ThemeProvider","PersistGate","_jsxs","Box","style","className","Routes","Route","path","element","home","proclipAndHolders","searchResults","Navigate","to","logIn","account","changePassword","yourOrders","upload","yourFavorites","order","news","fileDownload","newsLetter","aboutBrodit","findLocalRetailer","information","compare","notFound","pathname","match","open","handleClose","handleCloseError","clearPriceErrors","AppWrapper","DefaultRoute","replace","ReactDOM","render","Provider","Router","Suspense","fallback","document","getElementById","brandsNameCompare","brandNameA","brandNameB","otherModels","localeCompare","sortBrands","brandList","sort","replaceNameForBrandOther","result","brand","otherBrandIndex","findIndex","brandNames","brandName","GroupByName","combinedBrands","_result$groupBy$value","_result$groupBy","groupBy","values","newsDateComparer","aDate","Date","dateTime","bDate","getTime","newsArticleSelectors","fetchModteks","ids","post","productIds","fetchProduct","fetchProducts","shouldRun","item","_ref5","_ref6","filters","pagination","cleanFilters","filterValue","parameters","fetchFilteredProducts","valueObject","filter","_","extractSearchQueryFromUrlSearchParams","urlSearchParams","searchQuery","split","isSearchQueryEmpty","searchQueryObject","filteredSearchQuery","flat","createApi","baseQuery","fetchBaseQuery","baseUrl","endpoints","getNews","query","groups","join","transformResponse","_meta","languageSpecificNews","getNewsById","getOrderSystemMaintenance","getBigNews","getHeroNews","getFilesById","getRelatedProducts","getModTekProducts","getRelatedVideos","getModels","steerings","sortModels","getModelsForBrand","getYearsForModel","modelIds","brandIds","body","getReplacementProducts","getTechnicalInformationForProduct","getAltNameForProducts","setPreferredSteering","mutation","preferredSteering","authToken","useGetNewsQuery","useGetNewsByIdQuery","useGetOrderSystemMaintenanceQuery","useGetBigNewsQuery","useGetHeroNewsQuery","useGetFilesByIdQuery","useGetRelatedProductsQuery","useGetRelatedVideosQuery","useGetModelsQuery","useGetModelsForBrandQuery","useGetYearsForModelQuery","useGetReplacementProductsQuery","useGetModTekProductsQuery","useGetTechnicalInformationForProductQuery","useSetPreferredSteeringMutation","useGetAltNameForProductsQuery","cartSlice","step","number","items","shouldSync","setQty","i","index","quantity","add","setItems","del","empty","editNote","note","text","setShouldSync","nextOrderStep","prevOrderStep","putOrderId","resetOrderStep","batchAdd","addToCart","setCartItems","setShouldSyncCart","setQuantity","deleteCartRow","editCartNote","emptyCart","nextCartStep","prevCartStep","setOrderId","resetCartStep","batchAddToCart","apiCallBegan","createAction","apiCallSucess","apiCallFailed","persistScrollPosition","sessionStorage","transformProductForCompare","propertiesAsDisplayNameValue","properties","l","displayName","toLowerCase","compatibilityListString","compatibleModels","_x$years","years","placement","Set","newProd","isNew","yes","no","productTransformation","sectionMapping","Description","MappedFields","itemNumber","Field","description","eanNumber","DisplayDefaultValues","fitsFor","newProduct","technicalInformation","dimensionsAndWeight","height","depth","weight","volume","sections","s","section","Data","mf","sectionData","Values","notApplicable","priceAdapter","clearAll","addPrices","prices","loadCookie","serializedValue","cName","cookie","cStart","indexOf","cEnd","decodeURIComponent","substring","getCookie","saveCookie","validityInHours","expireDate","now","maxAge","maximumAge","expires","toUTCString","encodeURIComponent","createCookie","eraseCookie","favoriteSlice","favoriteProducts","setAllFavoriteProducts","addFavoriteProduct","removeFavoriteProduct","productId","removeFavoriteList","listName","addToFavoriteProducts","removeFromFavoriteProducts","setFavoriteProducts","setShouldSyncFavorites","deleteFavoriteList","getCart","onQueryStarted","_authToken","queryFulfilled","cartFromServer","batch","updateCart","clearCart","_ref7","useGetCartQuery","useUpdateCartMutation","useClearCartMutation","modelNameA","modelNameB","toUpperCase","expression","aParts","bParts","aPartAsInt","parseInt","bPartAsInt","diff","compareNumber","Math","sign","modelList","strings","LocalizedStrings","en","onlyOnlineShops","viaOurDistributors","pdfFiles","compatibleProducts","back","showSearch","hideSearch","tabInformation","moreInformation","tabSpecification","tabCompability","tabInstructions","tabRelatedProducts","tabRelatedFiles","noRelatedFiles","noAccessories","thereAreNoVideosForThisProduct","loadingMaterial","features","fasteners","compabilities","thisProductIsNotModelSpecific","loadingCompabilities","loadingProperties","propertiesNoneExist","instructions","chargingSpecification","unknownErrorCreatingOrder","showMore","showLess","noMaterialsAssigned","comingSoon","loadingProduct","createLeaflet","print","isComparing","share","image","productInformation","addToFavorites","removeFromFavorites","pickedByPro","newProductsForDevices","newProductsForVehicles","more","moreSmall","close","seeAll","hits","toggleLanguage","toggleView","email","password","repeatPassword","forgotPassword","passwordsMustMatch","forgotPasswordNotification","checkYourLoginDetails","theProduct","hasBeenAddedToCart","addressDetails","confirmation","yourCart","checkOrderDetails","summary","numberOfOrderLines","totalQuantity","total","addNote","qty","backToShop","backToCart","toCheckout","submitOrder","myDetails","customerNumber","messageToBrodit","purchaseOrder","orderPlacedBy","emailForOrderConfirmation","standardShippingAddress","billingAddress","orderConfirmation","thankYouForOrder","orderIsProcessing","orderNumber","orderDate","orderEmail","shippingAddress","reference","shop","shopViaReseller","findReseller","becomeReseller","new","showMoreNews","couldNotFindTheSelectedNewsArticle","newHolders","newProclip","broditsStory","broditsMovie","cookies","policies","integrityPolicy","contact","contactBrodit","hello","contactBroditVia","ifYouWantToChangeAnyInformation","hereIsYourUserInfo","workAtBrodit","findBrodit","noArticlesInCart","yourReference","registered","printed","deliveryTimeCannotBeConfirmed","processing","partiallyDelivered","deliveryComplete","date","orderWasPlaced","status","track","marking","numberOfProducts","trackShipment","backToOrderList","sentQuantity","anErrorOccuredTryRelogging","published","toggleSortOrder","searchOnDevice","searchOnVehicle","searchOnModel","searchOnModelYears","device","vehicle","showImages","howToInstall","phone","fax","thisSiteUsesCookies","readMore","readMoreInThePrivacyPolicy","iAccept","IHaveReadAndAcceptTheTerms","iHaveReadAndAgreeTo","broditABsConditionsAndTermsOfSale","companyAdress","purchase","delivery","validate","cancel","register","backwards","companyName","organisationNumber","website","contactPerson","phonenumber","streetAddress","postalCode","town","boxDeliveryAddress","deliveryAddress","postalAddress","companySignatory","attachUpToDateRegistrationCertificateFromBolagsverketAsAFile","chooseAFile","noFileHasBeenSelected","pleaseAcceptTheTermsAndConditionsAboveToContinue","pleaseFillInThisCheckBox","sendApplication","forParcelDelivery","forInvoiceThroughPdfBroditOnlySendsInvoicesThroughEmail","yourApplicationHasBeenSent","aProblemOccuredWhileProccessingYourApplication","pleaseTryAgainLaterOrContactBroditsSupportIfTheProblemPersists","couldNotConnectToTheServer","aProblemOccuredWhileProccessingYourApplicationPleaseTryAgainLaterOrContactBroditsSupportIfTheProblemPersists","models","modelYears","allProducts","loadMore","youSearchedFor","searchUpperCase","searchForProducts","premiereNewOnlineShop","beforeYouLogInInfo","returnNote","logOut","year","chooseYear","deselectAll","showOrHideFilters","yourEmail","yourName","receiversEmail","shareThis","orderByFile","orderByFileInfoParagraph1","orderByFileInfoParagraph2","clearYourCartFirst","orderWasImported","errorReadingOrderFile","clear","chosenFile","notIncludedArticlesMessage","couldNotBePlacedInCart","yourPasswordHasBeenChanged","ifYouHaveProblemsWithYourCartResetIt","youHaveSharedTheProduct","somethingWentWrongWhenSharingProduct","recaptchaError","unknownError","articleCouldNotBeAddedQuantityZero","experiencingProblemsWithCart","clickHere","toResetYourCart","endingSoon","chooseCity","shopOnline","thisPageWasNotFoundGoBackTo","phasingOut","showAmount","yourSearchGenerated","yourAccount","english","swedish","german","includePrices","updatesOnly","newItems","changedItems","deletedItems","isDeleted","isDiscontinuedAndNoLongerAvailable","removeItem","youMustChooseAType","formatShouldBeISO8601","download","errorWhenAttemptingToDownloadFile","noContentForTheSelectedLanguage","fromDate","webshopForBroditResellers","continueShopping","toSellBroditProducts","retailerApplicationText","thisProductIsNotAvailableOrder","country","useTemporaryAddress","zipAndCity","address","productNotFound","weCouldNotFindThisProductEtc","forInstanceKarlsborg","asLoggedInUserYouCanWithdraw","ifYouWantToWithdrawConsent","here","youMustThenAcceptTheTermsAgain","tryResettingPasswordAgain","fileDownloadIsNotAvailable","displaying","outOf","results","apiKey","badRequestFileDownload","unAuthorizedFileDownload","compareProducts","noProductsToCompare","compareMaxThreeArticles","compareMaxTwoArticles","toComparison","clearAllProducts","endComparison","thisProductIsNoLongerAvailable","parcel","orderSystemMaintenance","systemMaintenanceTryAgainLater","theProductWasReplacedWithFollowingProductProducts","wasReplacedByFollowingArticles","itWasReplacedByTheFollowingArticles","unregister","save","yourSubscriptionHasBeenUpdated","somethingWentWrong","whereCanIBuy","thePasswordMustAlsoComplyToTheFollowingRules","containMinimumSixCharacters","containUpperCaseCharacters","containLowerCaseCharacters","containANumber","containAFigure","productIsNotAvailable","withdrawingCookiesConsent","redirectingToStartPage","video","startPage","maximum30Letters","downloadCatalog","homeSection1Titel","homeSection1Text","findRightProclip","findRightHolder","homeSection2Titel","homeSection2Text","homeSectionPedestalHolderTitel","homeSectionPedestalHolderText","homeSectionPedestalHolderLinkText","homeSectionPipeHolderTitel","homeSectionPipeHolderText","homeSectionPipeHolderLinkText","homeSectionTruckHolderTitel","homeSectionTruckHolderText","homeSectionTruckHolderLinkText","homeSectionCustomSolutionsTitel","homeSectionCustomSolutionsText","howIsItMade","homeSection4Text","deviceHolder","proclip","seeProduct","homeSection5Title","homeSection5Text","proclipSection1Title","proclipSection1Text","proclipBrandsTitle","deviceBrandsTitle","proclipSection2ProclipText","proclipSection2HolderTitle","proclipSection2HolderText","proclipSection3ProclipBrands","proclipSection3ProclipDevices","productDevSection1Title","productDevSection1Text","productDevSection2Title","productDevSection2TextPart1","productDevSection2TextPart2","productDevSection2Part3Title","productDevSection2TextPart3","contactUs","productDevSection3Text","seeMore","seeLess","addArticleToCart","megaMenu","examplesSpecialCharacters","areYouSure","deleteAllConfirmation","exVat","downloadComparisonPdf","downloadProductPdf","findProClip","findDeviceHolder","customerDetails","myPagesEmail","refreshToContinue","adImageAlt","numbersOnly","smsTracking","cellNumber","homeSuctionTitle","homeSuctionText","homeSuctionLinkText","homeScreenTitle","homeScreenText","homeScreenLinkText","homeMoveClipTitle","homeMoveClipText","homeMoveClipLinkText","homeReadMoreAboutStrong","contactFullname","contactCompany","contactPhone","contactEmail","contactMessageTitle","contactSend","contactOfficeAndManufacturing","contactMailSent","newList","errorCreatingFavoriteList","myLists","selectLists","decreaseQuantity","increaseQuantity","deleteList","editList","unlisted","newName","selectProducts","noListIsEqualToOnlyFavorite","showUnlisted","showAllFavorites","seeProductVideo","selectOption","textField","playVideo","aboutProductDevelopment","aboutProclip","about","previousProductImage","nextProductImage","heartIcon","deleteListButton","signedInMenu","unavailable","consentCookiesPrompt","manageConsentButtonText","sv","getPrices","_ids","_err$error","useGetPricesQuery","getBrands","nameCorrectedBrands","getProductsByFilter","_response$pagedList$r","_response$pagedList","_response$pagedList$r2","productList","getModelYears","args","useGetBrandsQuery","useGetProductsByFilterQuery","useGetModelYearsQuery","selectDynamicPage","pageList","_pageList$filter","getContent","route","getDynamicPages","getDynamicPageMarkdown","markdownText","selectMarkdownText","dynamicPage","_dynamicPage$markdown","_dynamicPage$markdown2","_dynamicPage$markdown3","markdown","getDynamicPage","useGetContentQuery","useGetDynamicPagesQuery","useGetDynamicPageMarkdownQuery","useGetDynamicPageQuery","rejectWithValue","offset","fetchCustomerOrders","fetchCustomerOrder","getFavorite","favoriteFromServer","updateFavorite","useGetFavoriteQuery","useUpdateFavoriteMutation","materialSelectors","locale","useParams","priceSelectors","createTheme","props","MuiButtonBase","disableRipple","palette","primary","main","secondary","grey","contrastThreshold","background","typography","body2","fontSize","components","MuiInputBase","styleOverrides","borderColor","MuiOutlinedInput","border","MuiSelect","select","borderBottom","MuiButton","color","MuiLink","textDecorationColor","fontWeight","mobileBreakpoint","mobileMenuBreakpoint","productViewBreakpoint","desktopBreakpoint","midSizeBreakpoint","useSteering","_state$user$steering","useUser","useUserAuthToken","useUserData","useSelectedModTek","selectedModTek","snackPack","setMessage","_action$payload$sever","_action$payload$type","_action$payload$autoH","severity","autoHide","nextSnackPack","setSnackbarMessage","setDialogMessage","setNextSnackPack","searchSlice","setSearchQuery","updateSearchQuery","clearSearchQuery","userSlice","addresses","welcomeSplashVisible","currency","setUser","userData","showWelcomeSplash","toString","closeWelcomeSplash","signOut","setSteering","setSelectedModTek","signOutAction","signIn","changeSteering","changeSelectedModTek","selected","closeWelcome","showOverview","onComparePage","addToCompare","distinctResult","removeFromCompare","removeAllFromCompare","setShowCompareOverview","setIsOnComparePage","prevLimit","prevOffset","userSelectedLimit","increaseLimit","savePage","setLimit","setOffset","setUserSelectedLimit","increasePageLimit","resetCurrentPage","setPageLimit","setUserLimit","setPageOffset","settingsSlice","productGridView","proxyPath","recaptchaSiteKey","isShowingNavbarSearch","toggleProductGridView","setPP","setRCSK","setShowNavbarSearch","setShowNavbarSearchAction","toggleProductGridViewSetting","setProxyPath","setRecaptchaSiteKey","sitekey","shouldShow","monitorSlice","cartSimulation","cartSimulationLoading","loadingCustomerOrder","simulateOrderRequested","simulateOrderRequestReceived","simulateOrderFailed","resetPlacedOrder","fetchOrderRequestStarted","fetchOrderRequestReceived","fetchOrderFailed","simulateOrder","rows","resetOrder"],"mappings":"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","file":"static/js/main.5c76b53f.chunk.js","sourcesContent":["import { productAdapter } from \"./adapter/productAdapter\"\r\nimport { requestProduct, requestProducts, requestFilteredProducts } from \"./thunk/productThunk\"\r\nimport { prepareProducts } from \"../components/CompareProducts/helperFunctions\"\r\nimport { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nconst slice = createSlice({\r\n name: \"product\",\r\n initialState: productAdapter.getInitialState({\r\n modtekProducts: productAdapter.getInitialState(),\r\n relatedProducts: productAdapter.getInitialState(),\r\n lastProductFetch: [],\r\n lastFetchItemCount: 0,\r\n lastFetchProperties: {\r\n brands: [],\r\n productNames: []\r\n },\r\n loading: false,\r\n pendingRequests: 0\r\n }),\r\n reducers: {\r\n reset: () => {\r\n productAdapter.removeAll()\r\n },\r\n deleteSearchResult: state => {\r\n state.lastProductFetch = []\r\n state.lastFetchItemCount = 0\r\n state.lastFetchProperties = {\r\n brands: [],\r\n productNames: []\r\n }\r\n }\r\n },\r\n extraReducers: builder => {\r\n // Request one\r\n builder.addCase(requestProduct.pending, state => {\r\n state.pendingRequests += 1\r\n state.loading = Boolean(state.pendingRequests)\r\n })\r\n builder.addCase(requestProduct.fulfilled, (state, action) => {\r\n state.pendingRequests -= 1\r\n state.loading = Boolean(state.pendingRequests)\r\n\r\n const pagedList = action.payload?.pagedList.response\r\n if (!pagedList || pagedList.list.length === 0) {\r\n return\r\n }\r\n\r\n const products = prepareProducts(pagedList.list, action.meta.arg.lang)\r\n productAdapter.addOne(state, products[0])\r\n })\r\n\r\n builder.addCase(requestProduct.rejected, state => {\r\n state.pendingRequests -= 1\r\n state.loading = Boolean(state.pendingRequests)\r\n })\r\n\r\n builder.addCase(requestProducts.pending, state => {\r\n state.pendingRequests += 1\r\n state.loading = Boolean(state.pendingRequests)\r\n })\r\n builder.addCase(requestProducts.fulfilled, (state, action) => {\r\n state.pendingRequests -= 1\r\n state.loading = Boolean(state.pendingRequests)\r\n\r\n const pagedList = action.payload?.pagedList.response\r\n if (!pagedList || pagedList.list.length === 0) {\r\n return\r\n }\r\n\r\n const products = prepareProducts(pagedList.list, action.meta.arg.lang)\r\n\r\n const key = action.meta.arg.key\r\n\r\n switch (key) {\r\n case \"modtek\":\r\n productAdapter.removeAll(state.modtekProducts)\r\n productAdapter.addMany(state.modtekProducts, products)\r\n break\r\n case \"related\":\r\n productAdapter.removeAll(state.relatedProducts)\r\n productAdapter.addMany(state.relatedProducts, products)\r\n break\r\n default:\r\n productAdapter.addMany(state, products)\r\n }\r\n })\r\n builder.addCase(requestProducts.rejected, state => {\r\n state.pendingRequests -= 1\r\n state.loading = Boolean(state.pendingRequests)\r\n })\r\n\r\n // Request many\r\n builder.addCase(requestFilteredProducts.pending, state => {\r\n state.pendingRequests += 1\r\n state.loading = Boolean(state.pendingRequests)\r\n })\r\n builder.addCase(requestFilteredProducts.fulfilled, (state, action) => {\r\n state.pendingRequests -= 1\r\n state.loading = Boolean(state.pendingRequests)\r\n\r\n const pagedList = action.payload?.pagedList.response\r\n if (!pagedList) {\r\n return\r\n }\r\n\r\n const products = prepareProducts(pagedList.list, action.meta.arg.lang)\r\n state.lastProductFetch = products.map(x => x.originalId)\r\n state.lastFetchItemCount = pagedList.pagingHeader.totalItems\r\n state.lastFetchProperties = {\r\n brands: action.payload.brands,\r\n productNames: action.payload.names\r\n }\r\n\r\n productAdapter.addMany(state, products)\r\n })\r\n builder.addCase(requestFilteredProducts.rejected, state => {\r\n state.pendingRequests -= 1\r\n state.loading = Boolean(state.pendingRequests)\r\n })\r\n }\r\n})\r\n\r\nconst { reset, deleteSearchResult } = slice.actions\r\n\r\nexport default slice.reducer\r\n\r\nexport const resetProductsCache = () => dispatch => {\r\n dispatch(reset())\r\n}\r\n\r\nexport const clearSearchResult = () => dispatch => {\r\n dispatch(deleteSearchResult())\r\n}\r\n","import { filterFaultyValues } from \"../lib/helper/searchHelper\"\r\nimport { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nconst search2Slice = createSlice({\r\n name: \"search2\",\r\n reducers: {\r\n /**\r\n * Creates a new search query entry with the name of \"type\" containing\r\n * the value of \"value\".\r\n * @param {*} state The current state (using \"Immer\").\r\n * @param {object} payload An object containing two keys { type, value }.\r\n * payload.type {string} The name of the entry to create/override.\r\n * payload.value {object} The value of the search query entry.\r\n * Note: The payload.value object must follow the standard, that for each\r\n * key the value must be represented as an array, for example:\r\n * { customKeyword: [\"value1\", \"value2\", ...], anotherCustomKeyword: [\"another value\"], thirdCustomKeyword: [], ...}\r\n * Keys with faulty values, for example empty arrays and falsy values\r\n * will not be added.\r\n */\r\n setSearchQuery2: (state, { payload }) => {\r\n const { type, value, clearFilter } = payload\r\n if (clearFilter) state.searchQueries = {}\r\n state.searchQueries[type] = filterFaultyValues(value)\r\n },\r\n\r\n /**\r\n * Overrides a part of a search query entry with the name of \"type\" and\r\n * spreads in the value of \"value\".\r\n * @param {*} state The current state (using \"Immer\").\r\n * @param {object} payload An object containing two keys { type, value }.\r\n * payload.type {string} The name of the entry to create/update.\r\n * payload.value {object} The value you want to spread into the\r\n * search querys existing value.\r\n * Note: The payload.value object must follow the standard, that for each\r\n * key the value must be represented as an array, for example:\r\n * { customKeyword: [\"value1\", \"value2\", ...], anotherCustomKeyword: [\"another value\"], thirdCustomKeyword: [], ...}\r\n * Keys with faulty values, for example empty arrays and falsy values\r\n * will not be added.\r\n */\r\n updateSearchQuery2: (state, { payload }) => {\r\n const { type, value } = payload\r\n\r\n const newValue = {\r\n ...state.searchQueries[type],\r\n ...value\r\n }\r\n\r\n state.searchQueries[type] = filterFaultyValues(newValue)\r\n },\r\n\r\n /**\r\n * Removes all filters in the search query.\r\n * @param {*} state The current state (using \"Immer\").\r\n * @param {object} payload (Optional) An object containing the key { exclude }.\r\n * payload.exclude {Array} The search query keys specified in\r\n * this list will not be removed.\r\n */\r\n clearSearchQuery2: (state, { payload }) => {\r\n if (payload?.exclude) {\r\n // Removes all keys except the excluded keys\r\n const excludedSearchQueries = Object.entries(state.searchQueries)\r\n .reduce(\r\n (prev, [key, value]) => (\r\n payload.exclude.includes(key)\r\n ? { ...prev, [key]: value }\r\n : prev\r\n ),\r\n {}\r\n )\r\n\r\n state.searchQueries = excludedSearchQueries\r\n } else {\r\n state.searchQueries = {}\r\n }\r\n }\r\n },\r\n\r\n initialState: {\r\n /**\r\n * Search query entry inside the searchQueries object should always follow\r\n * the standard of \"componentNameResponsibleForThisQuery: { customKeyword: [], anotherCustomKeyword: [], ...}\r\n */\r\n searchQueries: {\r\n // Example structure:\r\n // vehicleSearchbar: { brands: [], models: [], years: [] },\r\n // deviceSearchbar: { brands: [], models: [] },\r\n // filterProducts: { brands: [], models: [], years: [], collections: [] },\r\n }\r\n }\r\n})\r\n\r\nexport const { setSearchQuery2, updateSearchQuery2, clearSearchQuery2 } = search2Slice.actions\r\nexport default search2Slice.reducer\r\n","/* eslint-disable import/prefer-default-export */\r\nimport { selectById } from \"../adapter/materialAdapter\"\r\nimport { createAsyncThunk } from \"@reduxjs/toolkit\"\r\nimport axios from \"axios\"\r\n\r\nconst internalLangConvert = lang => (lang === \"en\" ? \"EN1\" : \"SV1\")\r\n\r\nconst fetchMaterial = async (id, lang) => {\r\n const a = await axios.get(\r\n `/api/ProductInfo/MaterialDetails?materialId=${id}&lang=${internalLangConvert(lang)}`\r\n )\r\n return a.data\r\n}\r\n\r\nexport const requestMaterial = createAsyncThunk(\r\n \"material/fetchById\",\r\n async params => {\r\n const { id, lang } = params\r\n return fetchMaterial(id, lang)\r\n },\r\n {\r\n condition: (params, { getState }) => {\r\n const { id, lang } = params\r\n const existing = selectById(getState(), `${lang}-${id}`)\r\n return !existing\r\n }\r\n }\r\n)\r\n","/* eslint-disable no-nested-ternary */\r\n// Fyll på med alla saker från adaptern..\r\n\r\nimport { createEntityAdapter } from \"@reduxjs/toolkit\"\r\n\r\nexport const productAdapter = createEntityAdapter({\r\n selectId: product => product.id,\r\n sortComparer: (a, b) => (a.sortOrder > b.sortOrder ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0))\r\n})\r\n\r\nexport const modtekProductSelectors = productAdapter.getSelectors(\r\n state => state.product.modtekProducts\r\n)\r\n\r\nexport const relatedProductSelectors = productAdapter.getSelectors(\r\n state => state.product.relatedProducts\r\n)\r\n\r\nexport const { selectAll: selectAllModtekProducts, selectById: selectModtekProductById } = modtekProductSelectors;\r\n\r\nexport const { selectAll: selectAllRelatedProducts, selectById: selectRelatedProductById } = relatedProductSelectors;\r\n\r\nexport const productSelectors = productAdapter.getSelectors(state => state.product)\r\n\r\nexport const { selectById, selectAll } = productSelectors\r\n","import { makeStyles } from \"@mui/styles\"\r\n\r\nexport default makeStyles(() => ({\r\n root: {\r\n flex: \"0 1 100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\"\r\n },\r\n homePage: {\r\n width: \"100%\"\r\n }\r\n}))\r\n","import { requestCustomerOrders, requestCustomerOrder } from \"./thunk/customerOrderThunk\"\r\nimport { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nconst slice = createSlice({\r\n name: \"customerOrder\",\r\n initialState: {\r\n list: [],\r\n errors: []\r\n },\r\n reducers: {\r\n clearErrors: state => ({\r\n ...state,\r\n errors: []\r\n })\r\n },\r\n extraReducers: builder => {\r\n builder.addCase(requestCustomerOrders.fulfilled, (state, action) => {\r\n state.list = action.payload\r\n if (state.list === \"\") state.list = []\r\n })\r\n builder.addCase(requestCustomerOrders.rejected, (state, action) => {\r\n state.errors.push(action.payload)\r\n })\r\n builder.addCase(requestCustomerOrder.fulfilled, (state, action) => {\r\n state.list = action.payload\r\n if (state.list === \"\") state.list = []\r\n })\r\n builder.addCase(requestCustomerOrder.rejected, (state, action) => {\r\n state.errors.push(action.payload)\r\n })\r\n }\r\n})\r\n\r\nexport default slice.reducer\r\n\r\nconst { clearErrors } = slice.actions\r\n\r\nexport const clearCustomerOrderErrors = () => dispatch => dispatch(\r\n clearErrors()\r\n)\r\n","import { useEffect } from \"react\";\r\nimport { useSelector } from \"react-redux\";\r\n\r\nconst useErrors = () => {\r\n const priceErrors = useSelector(state => state.price.errors);\r\n const customerOrderErrors = useSelector(state => state.customerOrder.errors);\r\n\r\n useEffect(() => {\r\n\r\n }, [priceErrors, customerOrderErrors]);\r\n\r\n return priceErrors.length > 0 || customerOrderErrors.length > 0;\r\n}\r\n\r\nexport default useErrors;\r\n","/* eslint-disable no-return-assign */\r\n// https://gist.github.com/vre2h/d620ad389580e788b7482245fa62b06c\r\n\r\n// Specify reducers that should be saved to localstorage\r\nconst reducersToSave = [\"settings\", \"gdpr\"]\r\n\r\nexport const loadReducers = () => {\r\n try {\r\n const serializedReducers = localStorage.getItem(\"persistantReducers\")\r\n if (!serializedReducers) return undefined\r\n return JSON.parse(serializedReducers)\r\n } catch (err) {\r\n console.warn(err)\r\n return undefined\r\n }\r\n}\r\n\r\nexport const saveReducers = state => {\r\n const reducers = {}\r\n reducersToSave.forEach(key => reducers[key] = state[key])\r\n\r\n try {\r\n const serializedReducers = JSON.stringify(reducers)\r\n localStorage.setItem(\"persistantReducers\", serializedReducers)\r\n } catch (err) {\r\n console.warn(err)\r\n }\r\n}\r\n","/* eslint-disable consistent-return */\r\nimport * as actions from \"../api\"\r\nimport axios from \"axios\"\r\n\r\nconst api = ({ dispatch }) => next => async action => {\r\n if (action.type !== actions.apiCallBegan.type) return next(action)\r\n\r\n const {\r\n url, method, data, onStart, onSuccess, onError\r\n } = action.payload\r\n\r\n if (onStart) {\r\n dispatch({\r\n type: onStart\r\n })\r\n }\r\n\r\n next(action)\r\n\r\n try {\r\n const response = await axios.request({\r\n // baseURL: \"http:://localhost:62414\",\r\n url,\r\n method,\r\n data\r\n })\r\n // General\r\n dispatch(actions.apiCallSucess(response.data))\r\n // Specific\r\n if (onSuccess) {\r\n dispatch({\r\n type: onSuccess,\r\n payload: response.data\r\n })\r\n }\r\n } catch (error) {\r\n // General\r\n dispatch(actions.apiCallFailed(error.message))\r\n // Specific\r\n if (onError) {\r\n dispatch({\r\n type: onError,\r\n payload: error.message\r\n })\r\n }\r\n }\r\n}\r\n\r\nexport default api\r\n","import { materialAdapter } from \"./adapter/materialAdapter\";\r\nimport { requestMaterial } from \"./thunk/materialThunk\";\r\nimport { createSlice } from \"@reduxjs/toolkit\";\r\n\r\nconst slice = createSlice({\r\n name: \"material\",\r\n initialState: materialAdapter.getInitialState(),\r\n reducers: {},\r\n extraReducers: builder => {\r\n builder.addCase(requestMaterial.fulfilled, (state, action) => {\r\n materialAdapter.addOne(state, {\r\n ...action.payload,\r\n id: `${action.meta.arg.lang}-${action.payload.id}`,\r\n originalId: action.payload.id\r\n });\r\n });\r\n }\r\n});\r\n\r\nexport default slice.reducer;\r\n","import { selectAll } from \"../adapter/newsArticleAdapter\"\r\nimport { createAsyncThunk } from \"@reduxjs/toolkit\"\r\nimport axios from \"axios\"\r\n\r\nconst fetchNewsArticleById = async (id, lang) => {\r\n const a = await axios.get(`/api/news/${id}?language=${lang}`)\r\n return a.data\r\n}\r\n\r\nconst fetchNewsArticles = async ({\r\n lang, limit, group, includeFutureNews\r\n}) => {\r\n const groupParam = (group && group !== \"\") ? `&group=${group}` : \"\"\r\n const response = axios.get(`/api/news?language=${lang}&limit=${limit}&includeFutureNews=${includeFutureNews}${groupParam}`)\r\n return response.data\r\n}\r\n\r\n// const fetchNewsArticle = async (slug, lang) => {\r\n// const a = await axios.get(`/api/Pages/GetNewsArticle?slug=${slug}&language=${lang}`);\r\n// return a.data;\r\n// }\r\n\r\n// export const requestNewsArticle = createAsyncThunk('newsArticle/fetchBySlug',\r\n// async (params) => {\r\n// const { slug, lang } = params;\r\n// return await fetchNewsArticle(slug, lang);\r\n// },{\r\n// condition: (params, { getState }) => {\r\n// const { slug } = params;\r\n// const existing = selectAll(getState()).some(x => x.slug === slug);\r\n// return !existing;\r\n// }\r\n// }\r\n// );\r\n\r\nexport const requestNewsArticleById = createAsyncThunk(\r\n \"newsArticle/fetchById\",\r\n async params => {\r\n const { id, lang } = params\r\n return fetchNewsArticleById(id, lang)\r\n },\r\n {\r\n condition: (params, { getState }) => {\r\n const { id } = params\r\n const existing = selectAll(getState()).some(x => x.originalId === id)\r\n return !existing\r\n }\r\n }\r\n)\r\n\r\nexport const requestNewsArticles = createAsyncThunk(\r\n \"newsArticle/fetchAll\",\r\n async params => fetchNewsArticles(params)\r\n)\r\n","import { newsArticleAdapter } from \"./adapter/newsArticleAdapter\";\r\nimport { requestNewsArticleById, requestNewsArticles } from \"./thunk/newsArticleThunk\";\r\nimport { createSlice } from \"@reduxjs/toolkit\";\r\n\r\nconst slice = createSlice({\r\n name: \"newsArticle\",\r\n initialState: newsArticleAdapter.getInitialState(),\r\n reducers: {},\r\n extraReducers: builder => {\r\n builder.addCase(requestNewsArticleById.fulfilled, (state, action) => {\r\n newsArticleAdapter.addOne(state, {\r\n ...action.payload,\r\n id: `${action.meta.arg.lang}-${action.payload.id}`,\r\n originalId: action.payload.id\r\n })\r\n });\r\n builder.addCase(requestNewsArticles.fulfilled, (state, action) => {\r\n newsArticleAdapter.addMany(state, action.payload.map(article => ({\r\n ...article,\r\n id: `${action.meta.arg.lang}-${article.id}`,\r\n originalId: article.id\r\n }))); // meta.arg.lang = lang paramter\r\n });\r\n }\r\n})\r\n\r\nexport default slice.reducer;\r\n","import { modelNameCompare } from \"../../lib/helper/modelHelper\";\r\nimport { createEntityAdapter } from \"@reduxjs/toolkit\";\r\n\r\nexport const modelAdapter = createEntityAdapter({\r\n selectId: model => model.id,\r\n sortComparer: (a, b) => modelNameCompare(a.name, b.name)\r\n});\r\n\r\nexport const modelSelectors = modelAdapter.getSelectors(state => state.model);\r\n\r\nexport const { selectById, selectAll } = modelSelectors;\r\n","import { restoreNameForBrandOther } from \"../../lib/helper/brandHelper\"\r\nimport { selectById } from \"../adapter/modelAdapter\"\r\nimport { createAsyncThunk } from \"@reduxjs/toolkit\"\r\nimport axios from \"axios\"\r\n\r\nconst fetchModel = async id => {\r\n const response = await axios.get(`/api/v1/Models/${id}`)\r\n return response.data\r\n}\r\n\r\nconst fetchModelsForBrand = async (brandId, language, steering = null) => {\r\n const [restoredBrandId] = restoreNameForBrandOther([brandId])\r\n const steeringParams = steering ? `&steerings=${steering}` : \"\"\r\n const response = await axios.get(\r\n `/api/v1/Brands/${restoredBrandId}/Models?language=${language}${steeringParams}`\r\n )\r\n return response.data\r\n}\r\n\r\nexport const requestModel = createAsyncThunk(\r\n \"model/fetchById\",\r\n async params => {\r\n const { id } = params\r\n return fetchModel(id)\r\n },\r\n {\r\n condition: (params, { getState }) => {\r\n const { id } = params\r\n const existing = selectById(getState(), id)\r\n return !existing\r\n }\r\n }\r\n)\r\n\r\nexport const requestModelsByBrand = createAsyncThunk(\r\n \"model/fetchByBrand\",\r\n async ({ brandId, language, steering = null }) => (\r\n fetchModelsForBrand(brandId, language, steering)\r\n )\r\n)\r\n","import { modelAdapter } from \"./adapter/modelAdapter\"\r\nimport { requestModel, requestModelsByBrand } from \"./thunk/modelThunk\"\r\nimport { createSlice } from \"@reduxjs/toolkit\"\r\n\r\n// Then, handle actions in your reducers:\r\nconst modelSlice = createSlice({\r\n name: \"model\",\r\n initialState: modelAdapter.getInitialState({\r\n lastModelFetch: []\r\n }),\r\n reducers: {},\r\n extraReducers: builder => {\r\n builder.addCase(requestModel.fulfilled, (state, action) => {\r\n modelAdapter.addOne(state, action.payload)\r\n })\r\n builder.addCase(requestModelsByBrand.fulfilled, (state, action) => {\r\n state.lastModelFetch = action.payload.map(x => x.id)\r\n modelAdapter.addMany(state, action.payload)\r\n })\r\n }\r\n})\r\n\r\nexport default modelSlice.reducer\r\n","/* eslint-disable import/prefer-default-export */\r\nimport { restoreNameForBrandOther } from \"../../lib/helper/brandHelper\"\r\nimport { createAsyncThunk } from \"@reduxjs/toolkit\"\r\nimport axios from \"axios\"\r\n\r\nconst fetchCollectionsForModel = async (language, brandId) => {\r\n const [restoredBrandId] = restoreNameForBrandOther([brandId])\r\n const response = await axios.get(\r\n `/api/ProductInfo/GetCollectionsForBrand?language=${language}&brandId=${restoredBrandId}`\r\n )\r\n return response.data\r\n}\r\n\r\nexport const requestCollectionsForBrand = createAsyncThunk(\r\n \"collections/fetchForBrand\",\r\n async params => {\r\n const { lang, brandId } = params\r\n return fetchCollectionsForModel(lang, brandId)\r\n }\r\n)\r\n","import { requestCollectionsForBrand } from \"./thunk/collectionThunk\";\r\nimport { createSlice } from \"@reduxjs/toolkit\";\r\n\r\nconst slice = createSlice({\r\n name: \"collection\",\r\n initialState: [],\r\n reducers: {},\r\n extraReducers: builder => {\r\n builder.addCase(requestCollectionsForBrand.fulfilled, (state, action) => action.payload);\r\n }\r\n});\r\n\r\nexport default slice.reducer;\r\n","/* eslint-disable import/no-named-as-default */\r\nimport cartReducer from \"./cartSlice\"\r\nimport userReducer from \"./userSlice\"\r\nimport monitorReducer from \"./monitorSlice\"\r\nimport settingsReducer from \"./settingsReducer\"\r\nimport productReducer from \"./productReducer\"\r\nimport materialReducer from \"./materialReducer\"\r\nimport priceReducer from \"./priceSlice\"\r\nimport customerOrderReducer from \"./customerOrderReducer\"\r\nimport newsArticleReducer from \"./newsArticleReducer\"\r\nimport modelSlice from \"./modelSlice\"\r\nimport collectionReducer from \"./collectionReducer\"\r\nimport pageSlice from \"./pageReducer\"\r\nimport searchReducer from \"./searchReducer\"\r\nimport userMessageReducer from \"./userMessageSlice\"\r\nimport favoriteReducer from \"./favoriteSlice\"\r\nimport { broditWebApi } from \"./services/broditWebApi\"\r\nimport { contentApi } from \"./services/contentApi\"\r\nimport { cartApi } from \"./services/cartApi\"\r\nimport { favoriteApi } from \"./services/favoriteApi\"\r\nimport compareProductsReducer from \"./compareProductsReducer\"\r\nimport { priceApi } from \"./services/priceApi\"\r\nimport { productInfoApi } from \"./services/productInfoApi\"\r\nimport search2Reducer from \"./search2Reducer\"\r\nimport { combineReducers } from \"@reduxjs/toolkit\"\r\n\r\nexport const rootReducer = combineReducers({\r\n cart: cartReducer,\r\n user: userReducer,\r\n product: productReducer,\r\n material: materialReducer,\r\n monitor: monitorReducer,\r\n settings: settingsReducer,\r\n price: priceReducer,\r\n customerOrder: customerOrderReducer,\r\n newsArticle: newsArticleReducer,\r\n model: modelSlice,\r\n collection: collectionReducer,\r\n page: pageSlice,\r\n search: searchReducer,\r\n search2: search2Reducer,\r\n userMessage: userMessageReducer,\r\n favorite: favoriteReducer,\r\n compareProduct: compareProductsReducer,\r\n [broditWebApi.reducerPath]: broditWebApi.reducer,\r\n [contentApi.reducerPath]: contentApi.reducer,\r\n [cartApi.reducerPath]: cartApi.reducer,\r\n [favoriteApi.reducerPath]: favoriteApi.reducer,\r\n [priceApi.reducerPath]: priceApi.reducer,\r\n [productInfoApi.reducerPath]: productInfoApi.reducer\r\n})\r\n\r\nexport default rootReducer\r\n","/* eslint-disable import/no-extraneous-dependencies */\r\nimport { broditWebApi } from \"./services/broditWebApi\"\r\nimport api from \"./middleware/api\"\r\nimport { loadReducers } from \"./localStorage\"\r\nimport { rootReducer } from \"./rootReducer\"\r\nimport { contentApi } from \"./services/contentApi\"\r\nimport { cartApi } from \"./services/cartApi\"\r\nimport { favoriteApi } from \"./services/favoriteApi\"\r\nimport { priceApi } from \"./services/priceApi\"\r\nimport { productInfoApi } from \"./services/productInfoApi\"\r\nimport { setupListeners } from \"@reduxjs/toolkit/query\"\r\nimport { configureStore } from \"@reduxjs/toolkit\"\r\nimport thunk from \"redux-thunk\"\r\n\r\nimport { persistStore, persistReducer } from \"redux-persist\"\r\nimport storage from \"redux-persist/lib/storage\"\r\n\r\nconst persistConfig = {\r\n key: \"root\",\r\n storage,\r\n whitelist: [\"compareProduct\", \"user\"]\r\n}\r\n\r\nconst persistedReducer = persistReducer(persistConfig, rootReducer)\r\n\r\nconst store = configureStore({\r\n reducer: persistedReducer,\r\n preloadedState: {\r\n ...loadReducers()\r\n },\r\n middleware: getDefaultMiddleware => [\r\n ...getDefaultMiddleware({\r\n serializableCheck: false\r\n }).concat([\r\n broditWebApi.middleware,\r\n contentApi.middleware,\r\n cartApi.middleware,\r\n favoriteApi.middleware,\r\n priceApi.middleware,\r\n productInfoApi.middleware\r\n ]),\r\n thunk,\r\n api\r\n ]\r\n})\r\n\r\nconst persistor = persistStore(store)\r\n\r\n// optional, but required for refetchOnFocus/refetchOnReconnect behaviors (@reduxjs/toolkit/query)\r\n// see `setupListeners` docs - takes an optional callback as the 2nd arg for customization\r\nsetupListeners(store.dispatch)\r\n\r\nexport { store, persistor }\r\n","import useStyles from \"./styles\"\r\nimport theme from \"./theme\"\r\nimport { useLanguage } from \"./lib/hooks/languageHooks\"\r\nimport { strings as Localization } from \"./lib/Localization\"\r\nimport { clearCustomerOrderErrors } from \"./redux/customerOrderReducer\"\r\nimport useErrors from \"./redux/hook/errorHooks\"\r\nimport { useIsUserAuthorized } from \"./redux/hook/userHooks\"\r\nimport { saveReducers } from \"./redux/localStorage\"\r\nimport { clearPriceErrors } from \"./redux/priceSlice\"\r\nimport { store, persistor } from \"./redux/store\"\r\nimport { tabletBreakpoint } from \"./lib/helper/viewportHelper\"\r\nimport { useLogFrontendErrorMutation } from \"./redux/services/broditWebApi\"\r\nimport { ErrorBoundary } from \"react-error-boundary\"\r\nimport {\r\n Box, StyledEngineProvider, ThemeProvider, useMediaQuery\r\n} from \"@mui/material\"\r\nimport { useDispatch } from \"react-redux\"\r\nimport {\r\n Route, Routes, Navigate, useLocation\r\n} from \"react-router-dom\"\r\nimport React, { lazy } from \"react\"\r\nimport { PersistGate } from \"redux-persist/integration/react\"\r\nimport \"./cookie-manager-style.css\"\r\n\r\nconst CompareOverview = lazy(() => import(\"./components/CompareOverview/CompareOverview\"))\r\nconst CompareProducts = lazy(() => import(\"./components/CompareProducts/CompareProducts\"))\r\nconst CustomerOrderInfo = lazy(() => import(\"./components/CustomerOrders/CustomerOrderInfo/CustomerOrderInfo\"))\r\nconst CustomerOrders = lazy(() => import(\"./components/CustomerOrders/CustomerOrders\"))\r\nconst DynamicContentPage = lazy(() => import(\"./components/DynamicContentPage/DynamicContentPage\"))\r\nconst ErrorMessage = lazy(() => import(\"./components/ErrorMessage/ErrorMessage\"))\r\nconst FavoriteProductsPage = lazy(() => import(\"./components/Favorites/FavoriteProductPage/FavoriteProductsPage\"))\r\nconst FileDownload = lazy(() => import(\"./components/FileDownload/FileDownload\"))\r\nconst FilterProducts = lazy(() => import(\"./components/Products/FilterProducts/FilterProducts\"))\r\nconst FlashMessage = lazy(() => import(\"./components/FlashMessage/FlashMessage\"))\r\nconst Footer = lazy(() => import(\"./components/Footer/Footer\"))\r\nconst Home = lazy(() => import(\"./components/Home/Home\"))\r\nconst LandingPageMetaDescription = lazy(() => import(\"./components/MetaData/LandingPageMetaDescription\"))\r\nconst MessageNotification = lazy(() => import(\"./components/MessageNotification/MessageNotification\"))\r\nconst Navbar = lazy(() => import(\"./components/Navbar/Navbar\"))\r\nconst NewsLetter = lazy(() => import(\"./components/NewsLetter/NewsLetter\"))\r\nconst NewsListPage = lazy(() => import(\"./components/News/NewsListPage/NewsListPage\"))\r\nconst NewsMetaDescription = lazy(() => import(\"./components/MetaData/NewsMetaDescription\"))\r\nconst NewsPage = lazy(() => import(\"./components/News/NewsPage/NewsPage\"))\r\nconst NotFound = lazy(() => import(\"./components/NotFound/NotFound\"))\r\nconst Order = lazy(() => import(\"./components/Order/Order\"))\r\nconst OrderUpload = lazy(() => import(\"./components/OrderUpload/OrderUpload\"))\r\nconst Page = lazy(() => import(\"./components/Page/Page\"))\r\nconst ResetPassword = lazy(() => import(\"./components/ResetPassword/ResetPassword\"))\r\nconst SignIn = lazy(() => import(\"./components/SignIn/SignIn\"))\r\nconst StateHandler = lazy(() => import(\"./components/StateHandler/StateHandler\"))\r\nconst User = lazy(() => import(\"./components/User/User\"))\r\nconst VehicleNewsListPage = lazy(() => import(\"./components/News/VehicleNewsListPage/VehicleNewsListPage\"))\r\nconst PrivacyPolicy = lazy(() => import(\"./components/PrivacyPolicy/PrivacyPolicy\"))\r\nconst ContactPage = lazy(() => import(\"./components/ContactPage/ContactPage\"))\r\nconst About = lazy(() => import(\"./components/About/About\"))\r\nconst ProclipAndHolders = lazy(() => import(\"./components/ProclipAndHolders/ProclipAndHolders\"))\r\nconst CategoriesPage = lazy(() => import(\"./components/CategoriesPage/CategoriesPage\"))\r\nconst ProductDevelopment = lazy(() => import(\"./components/ProductDevelopment/ProductDevelopment\"))\r\nconst RetailersPage = lazy(() => import(\"./components/RetailersPage/RetailersPage\"))\r\nconst DesktopProductInfoNew = lazy(() => import(\"./components/Products/ProductInfo/components/DesktopProductInfoNew\"))\r\nconst QuickShop = lazy(() => import(\"./components/SpeedOrder/QuickShop\"))\r\nconst ErrorPage = lazy(() => import(\"./components/ErrorPage/ErrorPage\"))\r\nconst CookieManager = lazy(() => import(\"react-cookie-manager\").then(module => ({ default: module.CookieManager })))\r\nconst AboutPageMetaDescription = lazy(() => import(\"./components/MetaData/AboutMetaDescription\"))\r\nconst NoIndexMetaData = lazy(() => import(\"./components/MetaData/NoIndexMetadata\"))\r\nconst ProductDevelopmentMetaDescription = lazy(() => import(\"./components/MetaData/ProductDevelopmentMetaDescription\"))\r\nconst ProclipAndHoldersMetaDescription = lazy(() => import(\"./components/MetaData/ProclipAndHoldersMetaDescription\"))\r\nconst CategoriesMetaDescription = lazy(() => import(\"./components/MetaData/CategoriesMetaDescription\"))\r\nconst ProclipMetaDescription = lazy(() => import(\"./components\").then(module => ({ default: module.ProclipMetaDescription })))\r\nconst SignInMetaDescription = lazy(() => import(\"./components\").then(module => ({ default: module.SignInMetaDescription })))\r\nconst RouteChangeTracker = lazy(() => import(\"./components/RouteChangeTracker/RouteChangeTracker\"))\r\n\r\n// https://dev.to/link2twenty/react-redux-and-localstorage-2lih\r\n// https://medium.com/edonec/redux-can-be-made-easier-with-redux-toolkit-b1d2d17b90ba\r\n\r\nconst App = () => {\r\n const classes = useStyles()\r\n const language = useLanguage()\r\n const isAuthorized = useIsUserAuthorized()\r\n const errors = useErrors()\r\n const dispatch = useDispatch()\r\n const isTablet = useMediaQuery(theme.breakpoints.down(tabletBreakpoint))\r\n const [logFrontendError] = useLogFrontendErrorMutation()\r\n const location = useLocation()\r\n\r\n Localization.setLanguage(language)\r\n store.subscribe(() => saveReducers(store.getState()))\r\n\r\n const handleCloseError = () => {\r\n dispatch(clearPriceErrors())\r\n dispatch(clearCustomerOrderErrors())\r\n }\r\n\r\n return (\r\n logFrontendError({ error: error.message, stack: info.componentStack })}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n {/* */}\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n )\r\n : ()}\r\n />\r\n \r\n \r\n \r\n \r\n )\r\n : \r\n }\r\n />\r\n )\r\n : ()}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n )\r\n : ()}\r\n />\r\n )\r\n : ()}\r\n />\r\n \r\n \r\n \r\n )\r\n : ()}\r\n />\r\n } />\r\n } />\r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n } />\r\n {/* } /> */}\r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n } />\r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n } />\r\n } />\r\n } />\r\n } />\r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n \r\n \r\n )}\r\n />\r\n \r\n {isAuthorized && isTablet && location.pathname.match(/[^/]+$/)?.[0] !== \"categories\" && }\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n\r\n \r\n\r\n )\r\n}\r\n\r\nexport default App\r\n","import App from \"./App\"\r\nimport { store } from \"./redux/store\"\r\nimport React, { Suspense } from \"react\"\r\n\r\nimport ReactDOM from \"react-dom\"\r\nimport { Provider } from \"react-redux\"\r\nimport {\r\n BrowserRouter as Router, Route, Routes, Navigate\r\n} from \"react-router-dom\"\r\n\r\nconst AppWrapper = () => \r\n\r\nconst DefaultRoute = () => \r\n\r\nReactDOM.render(\r\n \r\n \r\n ...}>\r\n \r\n }\r\n />\r\n } />\r\n \r\n \r\n \r\n ,\r\n document.getElementById(\"root\")\r\n)\r\n","import { strings as Localization } from \"../Localization\"\r\n\r\nexport const brandsNameCompare = (brandNameA, brandNameB) => {\r\n // Force \"Other models\" to the top.\r\n if (brandNameA === Localization.otherModels) {\r\n return -1\r\n } if (brandNameB === Localization.otherModels) {\r\n return 1\r\n }\r\n return brandNameA.localeCompare(brandNameB)\r\n}\r\n\r\nexport const sortBrands = brandList => [...brandList].sort(\r\n (a, b) => brandsNameCompare(a.name, b.name)\r\n)\r\n\r\nexport const replaceNameForBrandOther = brandList => {\r\n // Make the result mutable\r\n const result = [...brandList.map(\r\n brand => ({ ...brand })\r\n )]\r\n\r\n // Replace the name of \",\" brand.\r\n const otherBrandIndex = result.findIndex(\r\n brand => brand.name === \",\"\r\n )\r\n if (otherBrandIndex !== -1) {\r\n result[otherBrandIndex].name = Localization.otherModels\r\n }\r\n\r\n return result\r\n}\r\n\r\nexport const restoreNameForBrandOther = brandNames => {\r\n // Make the result mutable\r\n const result = [...brandNames]\r\n\r\n // Replace the name of \",\" brand.\r\n const otherBrandIndex = result.findIndex(\r\n brandName => brandName === Localization.otherModels\r\n )\r\n if (otherBrandIndex !== -1) {\r\n result[otherBrandIndex] = \",\"\r\n }\r\n\r\n return result\r\n}\r\n\r\n// Is used by brands, models and years.\r\nexport const GroupByName = brandList => {\r\n const combinedBrands = brandList.reduce(\r\n (result, brand) => {\r\n const groupBy = brand.name\r\n const name = brand.name\r\n const value = [...(result[groupBy]?.value ?? []), brand]\r\n result[groupBy] = { id: name, name, value }\r\n\r\n return result\r\n },\r\n {}\r\n )\r\n\r\n return Object.values(combinedBrands)\r\n}\r\n\r\n/**\r\n * Searches through a list of items and attempts to find all items,\r\n * whose specified attribute is, present in the list of identifiers.\r\n * @param {*} identifiers The list of identifiers.\r\n * @param {*} items The list of items being \"filtered\"/searched.\r\n * @param {*} attributeToCompare Specifies a function for extracting an\r\n * attribute from the item. Used to match nested attributes against identifiers.\r\n * @returns A list of two items.\r\n * First item: A list of the items who matched against the identifiers.\r\n * Second item: A list of the identifiers without a match.\r\n */\r\n// Används inte just nu finns därför inte tester för denna\r\nexport const findItemsUsingIdentifier = (\r\n identifiers,\r\n items,\r\n attributeToCompare = (item => item)\r\n) => {\r\n const noMatchIds = [...(identifiers ?? [])]\r\n return [\r\n (\r\n items.filter(\r\n item => {\r\n const itemAttribute = attributeToCompare(item)\r\n const hasMatch = (identifiers ?? []).includes(itemAttribute)\r\n if (hasMatch) noMatchIds.splice(noMatchIds.indexOf(itemAttribute), 1)\r\n return hasMatch\r\n }\r\n )\r\n ),\r\n noMatchIds\r\n ]\r\n}\r\n\r\n/**\r\n * Finds the name of each object with a corresponding id.\r\n * @param {*} brandIds The ids to find the names for.\r\n * @param {*} allBrands The list of objects containing an 'id' key and a 'name' key.\r\n * @returns A list of two items.\r\n * First item: A list of names corresponding to the given ids.\r\n * Second item: A list of ids without a corresponding name.\r\n */\r\n// Används inte just nu finns därför inte tester för denna\r\nexport const findNamesFromIds = (brandIds, allBrands) => {\r\n const [matchedBrands, noMatchIds] = findItemsUsingIdentifier(\r\n brandIds,\r\n allBrands,\r\n brand => brand.id\r\n )\r\n\r\n return [\r\n matchedBrands.map(brand => brand.name),\r\n noMatchIds\r\n ]\r\n}\r\n\r\n/**\r\n * Finds the ids of each object with a corresponding name.\r\n * @param {*} brandNames The names to find the ids for.\r\n * @param {*} allBrands The list of objects containing an 'id' key and a 'name' key.\r\n * @returns A list of two items.\r\n * First item: A list of ids corresponding to the given names.\r\n * Second item: A list of names without any corresponding id.\r\n */\r\n// Används inte just nu finns därför inte tester för denna\r\nexport const findIdsFromNames = (brandNames, allBrands) => {\r\n const brandNamesLowerCase = brandNames.map(brandName => brandName.toLowerCase())\r\n const [matchedBrands, noMatchNames] = findItemsUsingIdentifier(\r\n brandNamesLowerCase,\r\n allBrands,\r\n brand => brand.name.toLowerCase()\r\n )\r\n\r\n return [\r\n matchedBrands.map(brand => brand.id),\r\n noMatchNames\r\n ]\r\n}\r\n","const newsDateComparer = (a, b) => {\r\n const aDate = new Date(a.dateTime)\r\n const bDate = new Date(b.dateTime)\r\n\r\n if (aDate.getTime() === bDate.getTime()) return 0 // TODO: Lägg till en localeCompare här så att man först jämför datum och sedan på localeCompare för samma datum.\r\n return aDate < bDate ? 1 : -1\r\n}\r\n\r\nconst sortNews = newsList => [...newsList].sort(\r\n (a, b) => newsDateComparer(a, b)\r\n)\r\n\r\nexport { newsDateComparer, sortNews }\r\n","import { newsDateComparer } from \"../../lib/helper/newsHelper\";\r\nimport { createEntityAdapter } from \"@reduxjs/toolkit\";\r\n\r\nexport const newsArticleAdapter = createEntityAdapter({\r\n selectId: newsArticle => newsArticle.id,\r\n sortComparer: newsDateComparer\r\n});\r\n\r\nexport const newsArticleSelectors = newsArticleAdapter.getSelectors(state => state.newsArticle)\r\n\r\nexport const { selectById, selectAll } = newsArticleSelectors;\r\n","import { replaceNameForBrandOther, restoreNameForBrandOther } from \"../../lib/helper/brandHelper\"\r\nimport {\r\n selectById, selectModtekProductById, selectRelatedProductById\r\n} from \"../adapter/productAdapter\"\r\nimport { createAsyncThunk } from \"@reduxjs/toolkit\"\r\nimport axios from \"axios\"\r\n\r\n// https://stackoverflow.com/questions/66968631/how-can-i-cache-data-that-i-already-requested-and-access-it-from-the-store-using\r\nconst fetchProduct = async (id, lang) => {\r\n const a = await axios.post(\"/api/ProductInfo/GetProductsByFilter\", { productIds: [id], language: lang })\r\n return a.data\r\n}\r\n\r\nconst fetchProducts = async (ids, lang) => {\r\n const a = await axios.post(\"/api/ProductInfo/GetProductsByFilter\", { productIds: ids, language: lang })\r\n return a.data\r\n}\r\n\r\nexport const fetchModteks = async (ids, lang) => {\r\n const a = await axios.post(\"/api/ProductInfo/GetProductsByFilter\", { productIds: ids, language: lang })\r\n return a.data.pagedList.response.list\r\n}\r\n\r\nconst fetchFilteredProducts = async ({ filters, pagination, lang }) => {\r\n // Filter out empty search keywords.\r\n const cleanFilters = Object.entries(filters).reduce((result, [key, value]) => (\r\n (value.length > 0)\r\n ? { ...result, [key]: value }\r\n : result\r\n ), {})\r\n\r\n // Prevent fetching when filter is empty.\r\n const isPopulated = Object.values(cleanFilters).some(\r\n filterValue => filterValue.length > 0\r\n )\r\n if (!isPopulated) return null\r\n\r\n // Restore the original name of the \"Other models\" brand.\r\n if (cleanFilters.brands) {\r\n cleanFilters.brands = restoreNameForBrandOther(cleanFilters.brands)\r\n }\r\n\r\n const parameters = { ...cleanFilters, ...pagination, language: lang }\r\n const response = await axios.post(\"/api/ProductInfo/GetProductsByFilter\", parameters)\r\n\r\n // Change name of brand \",\" to \"Other models\".\r\n response.data.brands = replaceNameForBrandOther(response.data.brands)\r\n\r\n return response.data\r\n}\r\n\r\nexport const requestProduct = createAsyncThunk(\r\n \"product/fetchById\",\r\n // Api\r\n async params => {\r\n const { id, lang } = params\r\n return fetchProduct(id, lang)\r\n },\r\n {\r\n condition: (params, { getState }) => {\r\n const { id, lang } = params\r\n const existing = selectById(getState(), `${lang}-${id}`)\r\n return !existing\r\n }\r\n }\r\n)\r\n\r\nexport const requestProducts = createAsyncThunk(\r\n \"product/fetchByIds\",\r\n // Api\r\n async params => {\r\n const { ids, lang, key } = params\r\n return fetchProducts(ids, lang, key)\r\n },\r\n {\r\n condition: (params, { getState }) => {\r\n const { ids, lang, key } = params\r\n const state = getState()\r\n\r\n if ((!ids || ids.length === 0 || state.product.loading) && !key) return false\r\n\r\n let shouldRun = false\r\n let product\r\n\r\n ids.forEach(item => {\r\n switch (key) {\r\n case \"modtek\":\r\n product = selectModtekProductById(state, `${lang}-${item.id}`)\r\n break\r\n case \"related\":\r\n product = selectRelatedProductById(state, `${lang}-${item.id}`)\r\n break\r\n default:\r\n product = selectById(state, `${lang}-${item.id}`)\r\n }\r\n\r\n if (!product) shouldRun = true\r\n })\r\n\r\n return shouldRun\r\n }\r\n }\r\n)\r\n\r\nexport const requestFilteredProducts = createAsyncThunk(\r\n \"product/fetchByFilter\",\r\n async (\r\n { filters, pagination, lang },\r\n { getState }\r\n ) => fetchFilteredProducts({ filters, pagination, lang }, { getState })\r\n // {\r\n // condition: ({ filters, pagination, lang }, { getState }) => {\r\n // // Filter out empty search keywords.\r\n // let cleanFilters = Object.entries(filters).reduce((result, [key, value]) => {\r\n // return (\r\n // (value.length > 0)\r\n // ? { ...result, [key]: value }\r\n // : result\r\n // );\r\n // }, {});\r\n\r\n // if (cleanFilters.length > 1) return true;\r\n\r\n // if (cleanFilters.length < 1) return false;\r\n\r\n // if (!cleanFilters.productIds) return true;\r\n\r\n // const existing = cleanFilters.productIds.map(id => selectAll(getState()).some(prod => prod.id === lang + '-' + id)).every(x => x === true);\r\n\r\n // return !existing;\r\n // }\r\n // }\r\n)\r\n","/**\r\n* @param {*} valueObject The searchQuery object you want to remove faulty entries from.\r\n* Note: The object must follow the standard, that for each\r\n* key the value must be represented as an array, for example:\r\n* { customKeyword: [\"value1\", \"value2\", ...], anotherCustomKeyword: [\"another value\"], thirdCustomKeyword: [], ...}\r\n* @returns The searchQuery object without faulty entries. Examples of faulty\r\n* entries are keys containing empty arrays, keys containing arrays with empty strings or falsy values.\r\n*/\r\nexport const filterFaultyValues = valueObject => Object.entries(valueObject)\r\n .map(\r\n ([key, values]) => [key, values.filter(Boolean)]\r\n )\r\n .filter(\r\n ([_, values]) => (values && values.length > 0)\r\n ).reduce(\r\n (result, [key, values]) => ({ ...result, [key]: values }),\r\n {}\r\n )\r\n\r\n/**\r\n * Converts a URLSearchParams object into a searchQuery object.\r\n * @param {URLSearchParams} urlSearchParams A URLSearchParams object.\r\n * @returns A searchQuery object.\r\n */\r\nexport const extractSearchQueryFromUrlSearchParams = urlSearchParams => {\r\n // Convert to array.\r\n const urlEntries = [...urlSearchParams.entries()]\r\n\r\n // Convert values into arrays.\r\n const parsedEntries = urlEntries.map(([key, value]) => {\r\n // Handle \"Other models\" edge case.\r\n if (value === \",\") return [key, [value]]\r\n\r\n return [key, value.split(\",\")]\r\n })\r\n\r\n const searchQuery = parsedEntries.reduce(\r\n (result, [key, value]) => ({ ...result, [key]: value }),\r\n {}\r\n )\r\n\r\n return filterFaultyValues(searchQuery)\r\n}\r\n\r\n/**\r\n * Evaluates if a searchQuery object is empty.\r\n * @param {*} searchQueryObject A search query object.\r\n * @returns Returns true if the search query object does not contain any values.\r\n */\r\nexport const isSearchQueryEmpty = searchQueryObject => {\r\n const filteredSearchQuery = filterFaultyValues(searchQueryObject)\r\n const flatValues = Object.values(filteredSearchQuery).flat()\r\n return flatValues.length <= 0\r\n}\r\n","// Need to use the React-specific entry point to import createApi\r\nimport { restoreNameForBrandOther } from \"../../lib/helper/brandHelper\"\r\nimport { sortModels } from \"../../lib/helper/modelHelper\"\r\nimport { newsArticleAdapter } from \"../adapter/newsArticleAdapter\"\r\nimport { createApi, fetchBaseQuery } from \"@reduxjs/toolkit/query/react\"\r\n\r\n// Define a service using a base URL and expected endpoints\r\nexport const broditWebApi = createApi({\r\n reducerPath: \"broditWebApi\",\r\n baseQuery: fetchBaseQuery({\r\n baseUrl: \"/api/\"\r\n }),\r\n endpoints: builder => ({\r\n getNews: builder.query({\r\n query: ({\r\n language, limit = 20, groups = [], includeFutureNews = false\r\n }) => {\r\n let params = \"?\"\r\n params += `language=${language}`\r\n params += `&limit=${limit}`\r\n params += `&includeFutureNews=${includeFutureNews}`\r\n params += groups.map(group => `&groups=${group}`).join(\"\")\r\n return `news${params}`\r\n },\r\n transformResponse: (response, _meta, arg) => {\r\n const languageSpecificNews = response.map(article => ({\r\n ...article,\r\n id: `${arg.language}-${article.id}`,\r\n originalId: article.id\r\n }))\r\n\r\n newsArticleAdapter.addMany(\r\n newsArticleAdapter.getInitialState(),\r\n languageSpecificNews\r\n )\r\n\r\n return languageSpecificNews\r\n }\r\n }),\r\n getNewsById: builder.query({\r\n query: ({ language, id }) => `news/${id}?language=${language}`,\r\n transformResponse: (response, _meta, arg) => {\r\n const languageSpecificNews = {\r\n ...response,\r\n id: `${arg.language}-${response.id}`,\r\n originalId: response.id\r\n }\r\n\r\n newsArticleAdapter.addOne(\r\n newsArticleAdapter.getInitialState(),\r\n languageSpecificNews\r\n )\r\n\r\n return languageSpecificNews\r\n }\r\n }),\r\n getOrderSystemMaintenance: builder.query({\r\n query: () => \"Users/IsOrderSystemUnderMaintenance\"\r\n }),\r\n getBigNews: builder.query({\r\n query: () => \"news/GetBigNews\"\r\n }),\r\n getHeroNews: builder.query({\r\n query: () => \"news/GetHeroNews\"\r\n }),\r\n getFilesById: builder.query({\r\n query: id => `ProductInfo/GetProductSheets/${id}`\r\n }),\r\n getRelatedProducts: builder.query({\r\n query: id => `RelatedProducts/${id}`\r\n }),\r\n getModTekProducts: builder.query({\r\n query: id => `RelatedProducts/Modtek/${id}`\r\n }),\r\n getRelatedVideos: builder.query({\r\n query: id => `RelatedVideos/${id}`\r\n }),\r\n getModels: builder.query({\r\n query: ({ language, steerings = null }) => {\r\n const steeringParams = steerings\r\n ? steerings.map(steering => `&steerings=${steering}`).join(\"\")\r\n : \"\"\r\n\r\n return `v1/Models?language=${language}${steeringParams}`\r\n },\r\n transformResponse: response => sortModels(response)\r\n }),\r\n getModelsForBrand: builder.query({\r\n query: ({ brandId, language, steerings = null }) => {\r\n const [restoredBrandId] = restoreNameForBrandOther([brandId])\r\n const steeringParams = steerings\r\n ? steerings.map(steering => `&steerings=${steering}`).join(\"\")\r\n : \"\"\r\n\r\n return `v1/Brands/${restoredBrandId}/Models?language=${language}${steeringParams}`\r\n },\r\n transformResponse: response => sortModels(response)\r\n }),\r\n getYearsForModel: builder.query({\r\n query: ({\r\n modelIds,\r\n brandIds,\r\n language,\r\n steerings\r\n }) => ({\r\n url: \"ProductInfo/GetModelYears\",\r\n method: \"POST\",\r\n body: {\r\n modelIds: modelIds,\r\n brandIds: restoreNameForBrandOther(\r\n brandIds\r\n ),\r\n language: language,\r\n steering: steerings\r\n }\r\n }),\r\n transformResponse: response => response.response\r\n }),\r\n getReplacementProducts: builder.query({\r\n query: id => `ProductInfo/GetReplacementProducts?id=${id}`\r\n }),\r\n getTechnicalInformationForProduct: builder.query({\r\n query: id => `ProductInfo/GetProductsHtmlText?id=${id}`\r\n }),\r\n getAltNameForProducts: builder.query({\r\n query: id => `ProductInfo/GetAltTextForProducts?id=${id}`\r\n }),\r\n setPreferredSteering: builder.mutation({\r\n query: body => ({\r\n url: `Users/SetPreferredSteering/${body.preferredSteering}`,\r\n method: \"POST\",\r\n body: {\r\n authToken: body.authToken\r\n }\r\n })\r\n }),\r\n logFrontendError: builder.mutation({\r\n query: body => ({\r\n url: \"Error/Log\",\r\n method: \"POST\",\r\n body: {\r\n error: body.error,\r\n stack: body.stack\r\n }\r\n })\r\n })\r\n })\r\n})\r\n\r\nexport const {\r\n useGetNewsQuery,\r\n useGetNewsByIdQuery,\r\n useGetOrderSystemMaintenanceQuery,\r\n useGetBigNewsQuery,\r\n useGetHeroNewsQuery,\r\n useGetFilesByIdQuery,\r\n useGetRelatedProductsQuery,\r\n useGetRelatedVideosQuery,\r\n useGetModelsQuery,\r\n useGetModelsForBrandQuery,\r\n useGetYearsForModelQuery,\r\n useGetReplacementProductsQuery,\r\n useGetModTekProductsQuery,\r\n useGetTechnicalInformationForProductQuery,\r\n useSetPreferredSteeringMutation,\r\n useGetAltNameForProductsQuery,\r\n useLogFrontendErrorMutation\r\n} = broditWebApi\r\n","import { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nexport const cartSlice = createSlice({\r\n name: \"cart\",\r\n initialState: {\r\n order: {\r\n step: 0,\r\n number: \"\"\r\n },\r\n items: [],\r\n shouldSync: false\r\n },\r\n reducers: {\r\n // Set to a determined quantity (needed in cart view)\r\n setQty: (state, action) => ({\r\n ...state,\r\n items: state.items.map((item, i) => (\r\n i === action.payload.index ? { ...item, quantity: action.payload.quantity } : item\r\n )),\r\n shouldSync: true\r\n }),\r\n add: (state, action) => ({\r\n ...state,\r\n items: [...state.items, { id: action.payload.id, quantity: action.payload.quantity }],\r\n shouldSync: true\r\n }),\r\n setItems: (state, action) => {\r\n state.items = action.payload\r\n state.shouldSync = true\r\n },\r\n del: (state, action) => ({\r\n ...state,\r\n items: [...state.items.filter((element, index) => index !== action.payload)],\r\n shouldSync: true\r\n }),\r\n empty: state => ({\r\n ...state,\r\n items: [],\r\n shouldSync: true\r\n }),\r\n editNote: (state, action) => ({\r\n ...state,\r\n items: state.items.map((item, i) => (\r\n i === action.payload.index ? { ...item, note: action.payload.text } : item\r\n )),\r\n shouldSync: true\r\n }),\r\n setShouldSync: (state, action) => {\r\n state.shouldSync = action.payload\r\n },\r\n nextOrderStep: state => ({\r\n ...state,\r\n order: {\r\n step: state.order.step + 1,\r\n number: state.order.number\r\n }\r\n }),\r\n prevOrderStep: state => ({\r\n ...state,\r\n order: {\r\n step: state.order.step - 1,\r\n number: state.order.number\r\n }\r\n }),\r\n putOrderId: (state, action) => ({\r\n ...state,\r\n order: {\r\n step: state.order.step,\r\n number: action.payload\r\n }\r\n }),\r\n resetOrderStep: state => ({\r\n ...state,\r\n order: {\r\n step: 0,\r\n number: state.order.number // Varför behålla egentligen\r\n }\r\n }),\r\n batchAdd: (state, action) => ({\r\n ...state,\r\n items: action.payload.map(item => ({ id: item.article, quantity: item.quantity })),\r\n shouldSync: true\r\n })\r\n }\r\n})\r\n\r\nexport default cartSlice.reducer\r\n\r\nconst {\r\n add, setItems, setShouldSync, del, empty,\r\n setQty, nextOrderStep, prevOrderStep, putOrderId,\r\n resetOrderStep, editNote, batchAdd\r\n} = cartSlice.actions\r\n\r\nexport const addToCart = (id, quantity) => dispatch => dispatch(\r\n add({\r\n id,\r\n quantity\r\n })\r\n)\r\n\r\nexport const setCartItems = items => dispatch => dispatch(\r\n setItems(items)\r\n)\r\n\r\nexport const setShouldSyncCart = shouldSync => dispatch => dispatch(\r\n setShouldSync(shouldSync)\r\n)\r\n\r\nexport const setQuantity = (quantity, index) => dispatch => dispatch(\r\n setQty({\r\n quantity,\r\n index\r\n })\r\n)\r\n\r\nexport const deleteCartRow = index => dispatch => dispatch(\r\n del(index)\r\n)\r\n\r\nexport const editCartNote = (text, index) => dispatch => dispatch(\r\n editNote({\r\n text,\r\n index\r\n })\r\n)\r\n\r\nexport const emptyCart = () => dispatch => dispatch(empty())\r\n\r\nexport const nextCartStep = () => dispatch => dispatch(nextOrderStep())\r\n\r\nexport const prevCartStep = () => dispatch => dispatch(prevOrderStep())\r\n\r\nexport const setOrderId = id => dispatch => dispatch(putOrderId(id))\r\n\r\nexport const resetCartStep = () => dispatch => dispatch(resetOrderStep())\r\n\r\nexport const batchAddToCart = items => dispatch => dispatch(batchAdd(items))\r\n","import { createAction } from \"@reduxjs/toolkit\";\r\n\r\nexport const apiCallBegan = createAction(\"api/callBegan\");\r\nexport const apiCallSucess = createAction(\"api/callSuccess\");\r\nexport const apiCallFailed = createAction(\"api/callFailed\");\r\n","/* eslint-disable array-callback-return */\r\nimport { strings as Localization } from \"../../lib/Localization\"\r\n\r\nexport const persistScrollPosition = id => {\r\n sessionStorage.setItem(\"scroll-position-product-id-marker\", id)\r\n}\r\n\r\nexport const transformProductForCompare = product => {\r\n // flatten out the product properties\r\n const propertiesAsDisplayNameValue = product.properties.reduce(\r\n (l, { displayName, value }) => ({ ...l, [displayName.toLowerCase()]: value }),\r\n {}\r\n )\r\n\r\n const compatibilityListString = product.compatibleModels.map(x => (x.brand !== \",\" ? `${x.brand} ${x.model} ${x.years ?? \"\"}` : null)).join(\"\\n\")\r\n const placement = [...new Set(product.compatibleModels.map(x => x.placement))].join(\"\\n\")\r\n\r\n const newProd = product.isNew ? Localization.yes : Localization.no\r\n\r\n const p = {\r\n ...product, ...propertiesAsDisplayNameValue, compatibilityListString, newProd, placement\r\n }\r\n\r\n return p\r\n}\r\n\r\nexport const productTransformation = products => {\r\n const sectionMapping = [\r\n {\r\n Description: Localization.product,\r\n MappedFields: [\r\n {\r\n Description: Localization.itemNumber,\r\n Field: \"originalId\"\r\n },\r\n {\r\n Description: Localization.name,\r\n Field: \"name\"\r\n },\r\n {\r\n Description: Localization.description,\r\n Field: \"description\"\r\n },\r\n {\r\n Description: Localization.eanNumber,\r\n Field: \"eanNumber\"\r\n },\r\n {\r\n Description: Localization.placement,\r\n Field: \"placement\",\r\n DisplayDefaultValues: true\r\n },\r\n {\r\n Description: Localization.fitsFor,\r\n Field: \"compatibilityListString\",\r\n DisplayDefaultValues: true\r\n },\r\n {\r\n Description: Localization.newProduct,\r\n Field: \"newProd\"\r\n },\r\n {\r\n Description: Localization.technicalInformation,\r\n Field: \"technicalInformation\"\r\n }\r\n ]\r\n },\r\n {\r\n Description: Localization.dimensionsAndWeight,\r\n MappedFields: [\r\n {\r\n Description: Localization.width,\r\n Field: \"width\",\r\n DisplayDefaultValues: true\r\n },\r\n {\r\n Description: Localization.height,\r\n Field: \"height\",\r\n DisplayDefaultValues: true\r\n },\r\n {\r\n Description: Localization.depth,\r\n Field: \"depth\",\r\n DisplayDefaultValues: true\r\n },\r\n {\r\n Description: Localization.weight,\r\n Field: \"weight\",\r\n DisplayDefaultValues: true\r\n },\r\n {\r\n Description: Localization.volume,\r\n Field: \"volume\",\r\n DisplayDefaultValues: true\r\n }\r\n ]\r\n }\r\n ]\r\n\r\n const sections = []\r\n\r\n sectionMapping.map(s => {\r\n const section = {\r\n Description: s.Description,\r\n Data: []\r\n }\r\n\r\n s.MappedFields.map(mf => {\r\n const sectionData = {\r\n Description: mf.Description,\r\n Values: []\r\n }\r\n\r\n let values = []\r\n\r\n values = products.map(x => {\r\n if (x[mf.Field] !== undefined) { // There is a value, take it\r\n return x[mf.Field]\r\n }\r\n if (mf.DisplayDefaultValues) { // Take default value\r\n return Localization.notApplicable\r\n }\r\n return x[mf.Field]\r\n })\r\n\r\n sectionData.Values = values\r\n\r\n section.Data.push(sectionData)\r\n })\r\n sections.push(section)\r\n })\r\n\r\n return sections\r\n}\r\n\r\nexport const prepareProducts = (products, language) => products.map(product => (\r\n {\r\n ...product,\r\n id: `${language}-${product.id}`,\r\n originalId: product.id\r\n }\r\n))\r\n","import { priceAdapter } from \"./adapter/priceAdapter\";\r\nimport { createSlice } from \"@reduxjs/toolkit\";\r\n\r\nconst slice = createSlice({\r\n name: \"price\",\r\n initialState: priceAdapter.getInitialState({\r\n errors: []\r\n }),\r\n reducers: {\r\n clearAll: state => {\r\n priceAdapter.removeAll(state);\r\n },\r\n clearErrors: state => ({\r\n ...state,\r\n errors: []\r\n }),\r\n add: (state, action) => {\r\n priceAdapter.addMany(state, action.payload);\r\n }\r\n }\r\n});\r\n\r\nexport default slice.reducer;\r\n\r\nconst { clearAll, clearErrors, add } = slice.actions;\r\n\r\nexport const clearPrices = () => dispatch => dispatch(\r\n clearAll()\r\n)\r\n\r\nexport const clearPriceErrors = () => dispatch => dispatch(\r\n clearErrors()\r\n)\r\n\r\nexport const addPrices = prices => dispatch => dispatch(\r\n add(prices)\r\n)\r\n","// https://gist.github.com/vre2h/d620ad389580e788b7482245fa62b06c\r\n\r\nfunction getCookie(cName) {\r\n if (document.cookie.length > 0) {\r\n let cStart = document.cookie.indexOf(`${cName}=`)\r\n if (cStart !== -1) {\r\n cStart = cStart + cName.length + 1\r\n let cEnd = document.cookie.indexOf(\";\", cStart)\r\n if (cEnd === -1) {\r\n cEnd = document.cookie.length\r\n }\r\n return decodeURIComponent(document.cookie.substring(cStart, cEnd))\r\n }\r\n }\r\n return \"\"\r\n}\r\n\r\nfunction createCookie(name, value, expireDate, maximumAge) {\r\n const expires = `; expires=${expireDate.toUTCString()}`\r\n const maxAge = `; max-age=${maximumAge}`\r\n document.cookie = `${name}=${encodeURIComponent(value)}${expires}${maxAge}; path=/`\r\n}\r\n\r\nexport const loadCookie = key => {\r\n try {\r\n const serializedValue = getCookie(key)\r\n if (!serializedValue) return undefined\r\n return JSON.parse(serializedValue)\r\n } catch (err) {\r\n console.warn(err)\r\n return undefined\r\n }\r\n}\r\n\r\nexport const saveCookie = (key, value, hours = null) => {\r\n const validityInHours = hours || 24\r\n const expireDate = new Date(Date.now() + (validityInHours * 60 * 60 * 1000))\r\n const maxAge = validityInHours * 60 * 60\r\n\r\n try {\r\n const serializedValue = JSON.stringify(value)\r\n createCookie(key, serializedValue, expireDate, maxAge)\r\n } catch (err) {\r\n console.warn(err)\r\n }\r\n}\r\n\r\nexport function eraseCookie(name) {\r\n document.cookie = `${name}=; Max-Age=0; path=/`\r\n}\r\n","import { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nexport const favoriteSlice = createSlice({\r\n name: \"favorite\",\r\n initialState: {\r\n favoriteProducts: [],\r\n shouldSync: false\r\n },\r\n reducers: {\r\n setAllFavoriteProducts: (state, action) => {\r\n state.favoriteProducts = action.payload\r\n state.shouldSync = true\r\n },\r\n addFavoriteProduct: (state, action) => {\r\n state.favoriteProducts.push(action.payload)\r\n state.shouldSync = true\r\n },\r\n removeFavoriteProduct: (state, action) => {\r\n state.favoriteProducts = state.favoriteProducts.filter(\r\n product => product.productId !== action.payload\r\n )\r\n state.shouldSync = true\r\n },\r\n setShouldSync: (state, action) => {\r\n state.shouldSync = action.payload\r\n },\r\n removeFavoriteList: (state, action) => {\r\n state.favoriteProducts = state.favoriteProducts.filter(\r\n product => product.listName !== action.payload\r\n )\r\n state.shouldSync = true\r\n }\r\n }\r\n})\r\n\r\nexport default favoriteSlice.reducer\r\n\r\nconst {\r\n setAllFavoriteProducts, addFavoriteProduct, removeFavoriteProduct, setShouldSync, removeFavoriteList\r\n} = favoriteSlice.actions\r\n\r\nexport const addToFavoriteProducts = productId => dispatch => dispatch(\r\n addFavoriteProduct(productId)\r\n)\r\n\r\nexport const removeFromFavoriteProducts = productId => dispatch => dispatch(\r\n removeFavoriteProduct(productId)\r\n)\r\n\r\nexport const setFavoriteProducts = productIds => dispatch => dispatch(\r\n setAllFavoriteProducts(productIds)\r\n)\r\n\r\nexport const setShouldSyncFavorites = shouldSync => dispatch => dispatch(\r\n setShouldSync(shouldSync)\r\n)\r\n\r\nexport const deleteFavoriteList = listName => dispatch => dispatch(\r\n removeFavoriteList(listName)\r\n)\r\n","import { emptyCart, setCartItems, setShouldSyncCart } from \"../cartSlice\"\r\nimport { createApi, fetchBaseQuery } from \"@reduxjs/toolkit/query/react\"\r\nimport { batch } from \"react-redux\"\r\n\r\nexport const cartApi = createApi({\r\n reducerPath: \"cartApi\",\r\n baseQuery: fetchBaseQuery({ baseUrl: \"/api/cart/\" }),\r\n endpoints: builder => ({\r\n\r\n getCart: builder.query({\r\n query: ({ authToken }) => `GetFromAuthToken?authToken=${authToken}`,\r\n // transformResponse: (response) => response?.response,\r\n\r\n async onQueryStarted({ _authToken }, { dispatch, queryFulfilled }) {\r\n // Request has started.\r\n try {\r\n const { data: cartFromServer } = await queryFulfilled\r\n // Request succeeded.\r\n // Batch prevents rerendering for each dispatch and\r\n // instead only rerenders once.\r\n batch(() => {\r\n dispatch(setCartItems(\r\n cartFromServer\r\n ))\r\n dispatch(setShouldSyncCart(false))\r\n })\r\n } catch (err) {\r\n // Request returned and error.\r\n }\r\n }\r\n }),\r\n\r\n updateCart: builder.mutation({\r\n query: ({ authToken, ...parameters }) => ({\r\n url: `UpdateFromAuthToken?authToken=${authToken}`,\r\n method: \"POST\",\r\n body: {\r\n ...parameters\r\n }\r\n })\r\n // transformResponse: (response) => response?.response,\r\n }),\r\n clearCart: builder.mutation({\r\n query: ({ authToken }) => ({\r\n url: `ClearCart?authToken=${authToken}`,\r\n method: \"POST\",\r\n body: {}\r\n }),\r\n // You can add cache manipulation here if necessary, but avoid hooks\r\n async onQueryStarted({ authToken }, { dispatch }) {\r\n try {\r\n batch(() => {\r\n dispatch(emptyCart())\r\n dispatch(setShouldSyncCart(false))\r\n })\r\n } catch (err) {\r\n console.error(\"Error clearig cart:\", err)\r\n }\r\n }\r\n })\r\n })\r\n})\r\n\r\nexport const { useGetCartQuery, useUpdateCartMutation, useClearCartMutation } = cartApi\r\n","/* eslint-disable no-plusplus */\r\nexport const modelNameCompare = (modelNameA, modelNameB) => {\r\n const a = modelNameA.toUpperCase()\r\n const b = modelNameB.toUpperCase()\r\n\r\n const expression = /(\\D*)(\\d*)/\r\n const aParts = a.split(expression).filter(Boolean)\r\n const bParts = b.split(expression).filter(Boolean)\r\n\r\n for (let i = 0; i < aParts.length && i < bParts.length; i++) {\r\n if (aParts[i].localeCompare(bParts[i]) !== 0) {\r\n const aPartAsInt = parseInt(aParts[i], 10)\r\n const bPartAsInt = parseInt(bParts[i], 10)\r\n // If one or more part is not an integer\r\n if (!aPartAsInt || !bPartAsInt) {\r\n return a.localeCompare(b)\r\n }\r\n\r\n const diff = aPartAsInt - bPartAsInt\r\n if (diff !== 0) {\r\n return diff\r\n }\r\n }\r\n }\r\n\r\n const compareNumber = `${a.length}`.localeCompare(`${b.length}`)\r\n return Math.sign(compareNumber)\r\n}\r\n\r\nexport const sortModels = modelList => [...modelList].sort(\r\n (a, b) => modelNameCompare(a.name, b.name)\r\n)\r\n","/* eslint-disable import/prefer-default-export */\r\nimport LocalizedStrings from \"react-localization\"\r\n\r\nexport const strings = new LocalizedStrings({\r\n en: {\r\n onlyOnlineShops: \"See only online shops\",\r\n findLocalRetailer: \"Find your local retailer\",\r\n viaOurDistributors: \"Brodit products are available via our distributors.\",\r\n pdfFiles: \"PDF-files\",\r\n compatibleProducts: \"Compatible models\",\r\n back: \"Go back\",\r\n showSearch: \"Show search area\",\r\n hideSearch: \"Hide search area\",\r\n tabInformation: \"Information\",\r\n moreInformation: \"More information\",\r\n tabSpecification: \"Specification\",\r\n tabCompability: \"Fits for\",\r\n tabInstructions: \"Instructions\",\r\n tabRelatedProducts: \"Accessories\",\r\n tabRelatedFiles: \"Documents\",\r\n noRelatedFiles: \"There are no documents for this product\",\r\n noAccessories: \"There are no accessories for this product.\",\r\n thereAreNoVideosForThisProduct: \"There are no videos for this product.\",\r\n itemNumber: \"Item no.\",\r\n loadingMaterial: \"Loading material\",\r\n features: \"Features\",\r\n fasteners: \"Fasteners\",\r\n compabilities: \"Fits the following models\",\r\n thisProductIsNotModelSpecific: \"This product is not model specific\",\r\n loadingCompabilities: \"Loading compabilities\",\r\n loadingProperties: \"Loading properties\",\r\n properties: \"Properties\",\r\n propertiesNoneExist: \"No properties apply to this product.\",\r\n instructions: \"Instructions for\",\r\n chargingSpecification: \"Charging specifications\",\r\n error: \"Error\",\r\n unknownErrorCreatingOrder: \"Unknown error creating order.\",\r\n showMore: \"Show more\",\r\n showLess: \"Show less\",\r\n noMaterialsAssigned: \"No features are assigned to this product.\",\r\n comingSoon: \"Coming soon\",\r\n loadingProduct: \"Loading product\",\r\n createLeaflet: \"Create leaflet\",\r\n print: \"Print\",\r\n compare: \"Compare\",\r\n isComparing: \"is being compared\",\r\n share: \"Share\",\r\n loading: \"Loading\",\r\n image: \"Image\",\r\n addToCart: \"Add to cart\",\r\n eanNumber: \"EAN-number\",\r\n productInformation: \"Product information\",\r\n addToFavorites: \"Add to favorites\",\r\n removeFromFavorites: \"Remove from favorites\",\r\n yourFavorites: \"Favorites\",\r\n newProduct: \"New product\",\r\n pickedByPro: \"Picked By Pro\",\r\n newProductsForDevices: \"New products for devices\",\r\n newProductsForVehicles: \"New products for vehicles\",\r\n more: \"More\",\r\n moreSmall: \"...more\",\r\n close: \"Close\",\r\n seeAll: \"Show all\",\r\n hits: \"hits\",\r\n toggleLanguage: \"Toggle language\",\r\n user: \"User\",\r\n cart: \"Cart\",\r\n toggleView: \"Toggle view\",\r\n logIn: \"Sign in\",\r\n email: \"E-mail\",\r\n password: \"Password\",\r\n repeatPassword: \"Repeat password\",\r\n changePassword: \"Change password\",\r\n forgotPassword: \"Forgot password\",\r\n passwordsMustMatch: \"The passwords must match\",\r\n forgotPasswordNotification: \"A mail for resetting the password has been sent to the given email if it exist in our system. The link is vaild for 30min.\",\r\n checkYourLoginDetails: \"Check your login details and try again.\",\r\n product: \"Product\",\r\n theProduct: \"The product\",\r\n hasBeenAddedToCart: \"has been added to the cart.\",\r\n addressDetails: \"Address details\",\r\n confirmation: \"Confirmation\",\r\n yourCart: \"Your cart\",\r\n checkOrderDetails: \"Please check your order carefully to make sure everything is correct.\",\r\n summary: \"Summary\",\r\n numberOfOrderLines: \"Number of order lines\",\r\n totalQuantity: \"Total quantity\",\r\n total: \"Total\",\r\n emptyCart: \"Empty cart\",\r\n addNote: \"Add note\",\r\n note: \"Note\",\r\n quantity: \"Order qty\",\r\n qty: \"Qty\",\r\n price: \"Price\",\r\n backToShop: \"Back to shop\",\r\n backToCart: \"Back to cart\",\r\n toCheckout: \"To checkout\",\r\n submitOrder: \"Submit order\",\r\n myDetails: \"My details\",\r\n customerNumber: \"Customer number:\",\r\n name: \"Name:\",\r\n messageToBrodit: \"Message to Brodit\",\r\n purchaseOrder: \"Purchase order | Marking\",\r\n orderPlacedBy: \"Order placed by | Reference\",\r\n emailForOrderConfirmation: \"E-mail (for order confirmation)\",\r\n standardShippingAddress: \"Standard shipping address\",\r\n billingAddress: \"Billing address\",\r\n orderConfirmation: \"Order confirmation\",\r\n thankYouForOrder: \"Thank you for ordering from Brodit!\",\r\n orderIsProcessing: \"Your order is now being processed. You will receive a confirmation via e-mail soon.\",\r\n orderNumber: \"Order number\",\r\n orderDate: \"Order date\",\r\n orderEmail: \"Order e-mail\",\r\n shippingAddress: \"Shipping address\",\r\n reference: \"Reference\", // Kanske inte nödvändig, ett datafält egentligen\r\n shop: \"Shop\",\r\n shopViaReseller: \"You can buy Brodit's products via reseller\",\r\n findReseller: \"Find a reseller\",\r\n becomeReseller: \"Become a distributor\",\r\n new: \"New\",\r\n news: \"News\",\r\n showMoreNews: \"Older news\",\r\n couldNotFindTheSelectedNewsArticle: \"Could not find the selected news article\",\r\n newHolders: \"New Holders\",\r\n newProclip: \"New ProClip\",\r\n newsLetter: \"Newsletter\",\r\n aboutBrodit: \"About Brodit\",\r\n broditsStory: \"Brodit's story\",\r\n broditsMovie: \"Brodit's movie\",\r\n cookies: \"Cookies\",\r\n values: \"Values\",\r\n policies: \"Policies\",\r\n integrityPolicy: \"Integrity policy\",\r\n contact: \"Contact\",\r\n contactBrodit: \"Contact Brodit\",\r\n hello: \"Hello\",\r\n contactBroditVia: \"Contact Brodit via \",\r\n ifYouWantToChangeAnyInformation: \" if you wish to change any information.\",\r\n hereIsYourUserInfo: \"Here is your user info.\",\r\n workAtBrodit: \"Work at Brodit\",\r\n findBrodit: \"Find Brodit\",\r\n noArticlesInCart: \"You have no articles in the cart.\",\r\n yourOrders: \"My orders\",\r\n yourReference: \"Your reference\",\r\n registered: \"Registered\",\r\n printed: \"Printed\",\r\n deliveryTimeCannotBeConfirmed: \"Delivery time cannot be confirmed\",\r\n processing: \"Processing\",\r\n partiallyDelivered: \"Partly dispatched\",\r\n deliveryComplete: \"Dispatched\",\r\n date: \"Date\",\r\n order: \"Order\",\r\n orderWasPlaced: \"Order is placed, please check your email for order confirmation.\",\r\n status: \"Status\",\r\n track: \"Track\",\r\n marking: \"Marking\",\r\n numberOfProducts: \"Number of products\",\r\n trackShipment: \"Track shipment\",\r\n backToOrderList: \"Back to order list\",\r\n sentQuantity: \"Sent quantity\",\r\n anErrorOccuredTryRelogging: \"An error occured. Try logging in again.\",\r\n published: \"Published\",\r\n toggleSortOrder: \"Toggle sort order\",\r\n sort: \"Sort by\",\r\n searchOnDevice: \"Choose device\",\r\n searchOnVehicle: \"Choose vehicle\",\r\n searchOnModel: \"Choose model\",\r\n searchOnModelYears: \"Choose year\",\r\n device: \"Device\",\r\n vehicle: \"Vehicle\",\r\n showImages: \"Show more images\",\r\n howToInstall: \"How to install\",\r\n phone: \"Phone\",\r\n fax: \"Fax\",\r\n thisSiteUsesCookies: \"This site uses Cookies.\",\r\n readMore: \"Read more\",\r\n readMoreInThePrivacyPolicy: \"Read more in the Privacy policy.\",\r\n iAccept: \"I accept\",\r\n IHaveReadAndAcceptTheTerms: \"I have read and agree to the terms.\",\r\n iHaveReadAndAgreeTo: \"I have read and agree to\",\r\n broditABsConditionsAndTermsOfSale: \"Brodit ABs conditions and terms of sale\",\r\n information: \"Information\",\r\n companyAdress: \"Company\",\r\n purchase: \"Purchase\",\r\n delivery: \"Delivery\",\r\n validate: \"Validate\",\r\n cancel: \"Cancel\",\r\n register: \"Register\",\r\n backwards: \"Back\",\r\n next: \"Next\",\r\n companyName: \"Company name\",\r\n organisationNumber: \"Organisation number\",\r\n website: \"Website\",\r\n contactPerson: \"Contact person\",\r\n phonenumber: \"Phone number\",\r\n streetAddress: \"Street address\",\r\n postalCode: \"Postal code\",\r\n town: \"Town\",\r\n boxDeliveryAddress: \"Box delivery address\",\r\n deliveryAddress: \"Delivery address\",\r\n postalAddress: \"Postal address\",\r\n companySignatory: \"Company signatory\",\r\n attachUpToDateRegistrationCertificateFromBolagsverketAsAFile: \"Attach up to date registration certificate from Bolagsverket (PRV) as a file in PDF-format.\",\r\n chooseAFile: \"Choose a file\",\r\n noFileHasBeenSelected: \"No file has been selected.\",\r\n pleaseAcceptTheTermsAndConditionsAboveToContinue: \"Please accept the terms and conditions above to continue.\",\r\n pleaseFillInThisCheckBox: \"Please fill in this check box.\",\r\n sendApplication: \"Send application\",\r\n forParcelDelivery: \"For parcel delivery\",\r\n forInvoiceThroughPdfBroditOnlySendsInvoicesThroughEmail: \"for invoice in PDF format (Brodit only sends invoices through email)\",\r\n yourApplicationHasBeenSent: \"Your application has been sent.\",\r\n aProblemOccuredWhileProccessingYourApplication: \"A problem occured while proccessing your application.\",\r\n pleaseTryAgainLaterOrContactBroditsSupportIfTheProblemPersists: \" Please try again later or contact Brodit if the problem persists.\",\r\n couldNotConnectToTheServer: \"Could not connect to the server.\",\r\n aProblemOccuredWhileProccessingYourApplicationPleaseTryAgainLaterOrContactBroditsSupportIfTheProblemPersists: \"A problem occured while proccessing your application. Please try again later or contact Brodits support if the problem persists.\",\r\n models: \"Model\",\r\n modelYears: \"Model year\",\r\n otherModels: \"Other models\",\r\n products: \"Products\",\r\n allProducts: \"All products\",\r\n loadMore: \"Load more\",\r\n searchResults: \"Search results\",\r\n youSearchedFor: \"You searched for\",\r\n search: \"Search\",\r\n searchUpperCase: \"SEARCH\",\r\n searchForProducts: \"Search for products\",\r\n premiereNewOnlineShop: \"Premiere new online shop\",\r\n beforeYouLogInInfo: \"Updated shop requires updated password... Reset your password before logging in the first time (use the feature below). Thank you!\",\r\n returnNote: \"Return note\",\r\n logOut: \"Sign out\",\r\n year: \"Year\",\r\n chooseYear: \"CHOOSE YEAR\",\r\n deselectAll: \"DESELECT ALL\",\r\n showOrHideFilters: \"Show or hide filters\",\r\n yourEmail: \"Your e-mail\",\r\n yourName: \"Your name\",\r\n receiversEmail: \"Receivers e-mail\",\r\n message: \"Message\",\r\n shareThis: \"Share this\",\r\n orderByFile: \"Order by file\",\r\n orderByFileInfoParagraph1: \"For easier order placement you can upload an order-file into our web shop. You can export the file from your own system, and then upload it directly into your cart. This saves you time and eliminates type errors!\",\r\n orderByFileInfoParagraph2: \"Specifications: The file must be a comma separated text file. Usually, it is easiest to save your file as a csv-file directly from Excel or similar applications, but any text file will work as long as the numbers are delimited by commas or semi-colons. The file should contain item numbers and quantities only (Column A: Item no, Column B: Quantity)\",\r\n upload: \"Upload\",\r\n clearYourCartFirst: \"You already have items in your cart. Please clear it to continue.\",\r\n orderWasImported: \"Your order is now imported to the cart.\",\r\n errorReadingOrderFile: \"There was an error reading the order import file. Please try another file.\",\r\n clear: \"Clear\",\r\n chosenFile: \"Chosen file\",\r\n notIncludedArticlesMessage: \"The following articles are not found or not for sale\",\r\n couldNotBePlacedInCart: \"could not be placed in cart, it is not for sale or does not exist.\",\r\n yourPasswordHasBeenChanged: \"Your password has been changed.\",\r\n ifYouHaveProblemsWithYourCartResetIt: \"If you have problems with your cart, you can click here to reset it.\",\r\n youHaveSharedTheProduct: \"You have shared the product.\",\r\n somethingWentWrongWhenSharingProduct: \"Something went wrong when sharing the product.\",\r\n recaptchaError: \"Something went wrong with Recaptcha.\",\r\n unknownError: \"An unknown error occured.\",\r\n articleCouldNotBeAddedQuantityZero: \"The article cannot be added with quantity zero.\",\r\n experiencingProblemsWithCart: \"Experiencing problems with the cart? \",\r\n clickHere: \"Click here\",\r\n toResetYourCart: \" to reset (empty) it.\",\r\n endingSoon: \"Ending Soon\",\r\n chooseCity: \"CHOOSE CITY\",\r\n shopOnline: \"Shop online\",\r\n notFound: \"Not found\",\r\n thisPageWasNotFoundGoBackTo: \"This page was not found. Go to \",\r\n home: \"Mounting platform specialist!\",\r\n phasingOut: \"Few left\",\r\n brands: \"Brand\",\r\n showAmount: \"Show amount\",\r\n yourSearchGenerated: \"Your search generated\",\r\n account: \"Account\",\r\n fileDownload: \"File download\",\r\n yourAccount: \"My account\",\r\n language: \"Language\",\r\n english: \"English\",\r\n swedish: \"Swedish\",\r\n german: \"German\",\r\n includePrices: \"Include prices\",\r\n updatesOnly: \"Updates only\",\r\n newItems: \"New items\",\r\n changedItems: \"Changed items\",\r\n deletedItems: \"Deleted items\",\r\n isDeleted: \"Is deleted\",\r\n isDiscontinuedAndNoLongerAvailable: \"is discontinued and is no longer available\",\r\n removeAll: \"Remove all\",\r\n removeItem: \"Remove item\",\r\n youMustChooseAType: \"You must choose a type of data.\",\r\n formatShouldBeISO8601: \"Format should be YYYY-MM-DD.\",\r\n download: \"Download\",\r\n errorWhenAttemptingToDownloadFile: \"Error when attempting to download file.\",\r\n type: \"Type\",\r\n noContentForTheSelectedLanguage: \"No content for the selected language.\",\r\n fromDate: \"From date\",\r\n webshopForBroditResellers: \"Online shop for Brodit distributors\",\r\n continueShopping: \"Continue shopping\",\r\n toSellBroditProducts: \"To sell Brodit products\",\r\n retailerApplicationText: `Brodit is represented worldwide via experienced\r\n and valued distributors. For unrepresented countries, there’s an opening\r\n for companies who are passionate about service, quality and innovative\r\n ideas. If that applies to you, please tell us about your current\r\n business areas as well as your visions for Brodit products in your\r\n country in an e-mail to exportsales@brodit.se. Thank you!`,\r\n thisProductIsNotAvailableOrder: \"This item is included in your order but you can only see the item number, you can not see the product name or what it fits for.\",\r\n country: \"Country\",\r\n useTemporaryAddress: \"Send this order to a temporary shipping address\",\r\n zipAndCity: \"Zip and city\",\r\n address: \"Address\",\r\n productNotFound: \"Product not found\",\r\n weCouldNotFindThisProductEtc: \"We could not find this product. The product does not exist.\",\r\n forInstanceKarlsborg: \"I.e. \\\"54634 Karlsborg\\\"\",\r\n asLoggedInUserYouCanWithdraw: \"You can withdraw your consent at any time at your user profile or on the Privacy page under Documents.\",\r\n ifYouWantToWithdrawConsent: \"If you want to withdraw your consent to cookies, click \",\r\n here: \"here\",\r\n youMustThenAcceptTheTermsAgain: \"You must then accept the privacy terms again to be able to sign in.\",\r\n tryResettingPasswordAgain: \"It seems like the token is not valid. Try resetting your password again.\",\r\n fileDownloadIsNotAvailable: \"File download is under development and is not available for now.\",\r\n displaying: \"Displaying\",\r\n outOf: \"out of\",\r\n results: \"results\",\r\n apiKey: \"API key\",\r\n badRequestFileDownload: \"Error in input when downloading file. Is API key in correct format?\",\r\n unAuthorizedFileDownload: \"Error trying to verify API key when downloading file. Check with Brodit that you are allowed to download file.\",\r\n compareProducts: \"Compare products\",\r\n noProductsToCompare: \"No products has been added for compare\",\r\n description: \"Description\",\r\n placement: \"Placement\",\r\n fitsFor: \"Fits for\",\r\n technicalInformation: \"Technical information\",\r\n dimensionsAndWeight: \"Dimensions & weight\",\r\n width: \"Width\",\r\n height: \"Height\",\r\n depth: \"Depth\",\r\n weight: \"Weight\",\r\n volume: \"Volume\",\r\n yes: \"Yes\",\r\n no: \"No\",\r\n compareMaxThreeArticles: \"You can compare up to three articles at a time.\",\r\n compareMaxTwoArticles: \"You can only compare two articles\",\r\n toComparison: \"To comparison\",\r\n notApplicable: \"Not applicable\",\r\n clearAllProducts: \"Clear all products\",\r\n endComparison: \"End comparison\",\r\n thisProductIsNoLongerAvailable: \"This product is no longer available.\",\r\n parcel: \"Parcel\",\r\n orderSystemMaintenance: \"Our order system is currently under maintenance. During this time you can't login and use some services on the site. Refresh the page in a while and try again. Sorry for the inconvenience.\",\r\n systemMaintenanceTryAgainLater: \"There is currently a system maintenance, please try again later.\",\r\n theProductWasReplacedWithFollowingProductProducts: \"The product was replaced by the following product(s).\",\r\n wasReplacedByFollowingArticles: \" was replaced by the following articles.\",\r\n itWasReplacedByTheFollowingArticles: \"It was replaced by the following articles: \",\r\n action: \"Action\",\r\n unregister: \"Unregister\",\r\n save: \"Save\",\r\n yourSubscriptionHasBeenUpdated: \"Your newsletter subscription has been updated.\",\r\n somethingWentWrong: \"Something went wrong.\",\r\n whereCanIBuy: \"Where can I buy?\",\r\n thePasswordMustAlsoComplyToTheFollowingRules: \"The password must comply to the following rules:\",\r\n containMinimumSixCharacters: \"Contain minimum six characters\",\r\n containUpperCaseCharacters: \"Contain uppercase characters\",\r\n containLowerCaseCharacters: \"Contain lowercase characters\",\r\n containANumber: \"Contain a number\",\r\n containAFigure: \"Contain a special character\",\r\n productIsNotAvailable: \"Product is not available\",\r\n withdrawingCookiesConsent: \"Withdrawing cookies consent...\",\r\n redirectingToStartPage: \"Redirecting to start page...\",\r\n video: \"Video\",\r\n startPage: \"landing page\",\r\n maximum30Letters: \"This field can contain maximum 30 letters.\",\r\n downloadCatalog: \"Download catalog\",\r\n homeSection1Titel: \"Model specific Two-Part Solution\",\r\n homeSection1Text: \"Our ProClip and Device Holders are custom-designed for both your device and your specific vehicle model. The ProClip is seamlessly installed into the interior gaps without causing any damage or permanent modifications. Find the solution tailored to your needs using our search tool below. If you can't find what you're looking for, please contact us, and we'll be happy to assist you further.\",\r\n findRightProclip: \"Find the right ProClip for your vehicle\",\r\n findRightHolder: \"Holder for your device\",\r\n homeSection2Titel: \"Stronger Mounting Solutions\",\r\n homeSection2Text: \"Are you using a tablet, barcode scanner, payment terminal, or any other mobile device that needs to be mounted in a forklift, construction machine, or a truck? Whatever your needs are, we have a solution for you! With our wide range of products, we offer customized solutions for all types of environments, whether it's in the office, warehouse, or even in the air. We ensure that your devices are within reach, even under the most challenging conditions.\",\r\n homeSectionPedestalHolderTitel: \"Pedestal Mounts\",\r\n homeSectionPedestalHolderText: \"Modular, lightweight, and exceptionally strong - that's our range of aluminum pedestals designed for mounting heavier devices for everyday use in demanding environments.\",\r\n homeSectionPedestalHolderLinkText: \"Learn more about pedestal mounts\",\r\n homeSectionPipeHolderTitel: \"Pipe Mounts\",\r\n homeSectionPipeHolderText: \"Robust Pipe Mounts that easily attach to pipes and bars. Their applications are versatile, ranging from trucks, forklifts, carts, boats to airplanes.\",\r\n homeSectionPipeHolderLinkText: \"Learn more about pipe mounts\",\r\n homeSectionTruckHolderTitel: \"Forklift Mounts\",\r\n homeSectionTruckHolderText: \"Warehouse environments often involve heavy equipment and demanding conditions. For device mounting in these environments, sturdy mounts capable of withstanding stress and vibrations are required.\",\r\n homeSectionTruckHolderLinkText: \"Learn more about forklift mounts\",\r\n homeSectionCustomSolutionsTitel: \"Customized Solutions\",\r\n homeSectionCustomSolutionsText: \"At our factory in Karlsborg, Sweden, both development and manufacturing take place. If your company or operation has specific needs and requirements, our team of designers is ready to collaborate with you to create tailored solutions and products.\",\r\n howIsItMade: \"Read more\",\r\n homeSection4Text: \"The market introduces new vehicles and devices daily. For over four decades we've equipped ourselves with the knowledge and network required to rapidly develop, manufacture, and deliver products to a market that is constantly evolving.\",\r\n deviceHolder: \"Device Holders\",\r\n proclip: \"ProClip\",\r\n seeProduct: \"Show product\",\r\n homeSection5Title: \"Do you need help finding the right products?\",\r\n homeSection5Text: \"Contact us and describe your needs, and we'll assist you in finding the best solution for you!\",\r\n proclipAndHolders: \"ProClip and Device Holders\",\r\n proclipSection1Title: \"Model specific ProClip Mounts and Device Holders\",\r\n proclipSection1Text: \"Our two-part mounting solution provides you with a tailored device installation perfectly suited to your needs. One part consists of a Device Holder designed to fit your mobile phone, tablet, or other handheld device precisely. This is combined with a ProClip, which is a mount built specifically for your car model. The ProClip is installed in the car completely without screws, therefore causing no damage to the interior. Flexible, stable and secure - Simple!\",\r\n proclipBrandsTitle: \"We offer ProClips for vehicles from a wide range of brands, including:\",\r\n deviceBrandsTitle: \"We offer holders for devices from a wide range of brands, including:\",\r\n proclipSection2ProclipText: \"The ProClip serves as the mounting platform for the Device Holder. The purpose of our ProClip is to enable a stable and secure installation of the Device Holder in the vehicle, without the need for any permanent alterations such as drilling or screwing into the instrument panel. Instead, the ProClip is securely attached to the vehicle's existing gaps, panels, or seams on the dashboard. In many cases, it is further secured with double-sided adhesive tape specially designed not to leave any residue if you choose to remove or relocate the ProClip. Each ProClip is specifically designed for each car make and model, and the development of a new ProClip is a craftsmanship done on-site for each car and truck. Typically we develop a couple of ProClips for each vehicle model to offer a variety of mounting options.\",\r\n proclipSection2HolderTitle: \"Device Holders\",\r\n proclipSection2HolderText: \"The Device Holder is also specifically designed for your smartphone, GPS, or other mobile device. Various options are offered based on whether you have the device with or without a case, desire charging with a cable or wirelessly, or a passive holder without charging. In addition to our model specific device holders, we also offer adjustable holders that can be customized in height or width depending on the device you use it for.\",\r\n proclipSection3ProclipBrands: \"ProClip is available for all of these brands\",\r\n proclipSection3ProclipDevices: \"We offer Device Holders for a wide range of brands, including these\",\r\n productDevSection1Title: \"Customized solutions\",\r\n productDevSection1Text: \"In cases where our existing range is insufficient to meet the customer's needs, we have the opportunity to create a customized mounting solution.\",\r\n productDevSection2Title: \"Needs analysis\",\r\n productDevSection2TextPart1: \"The process begins with direct communication between you, our sales representatives, and product developers. Together, we identify needs and potential solutions.\",\r\n productDevSection2TextPart2: \"The needs can vary depending on how and where the device will be used. These needs include factors such as challenging environments, technical specifications, charging and data transfer requirements, and more.\",\r\n productDevSection2Part3Title: \"Cost estimation and prototype\",\r\n productDevSection2TextPart3: \"When we have achieved a common understanding of how the product should be designed, we present a development cost. If this cost is approved, we proceed to manufacture a prototype. The prototype can be a functional, CNC-machined version or, in some cases, a 3D-printed prototype.\",\r\n contactUs: \"Contact us\",\r\n productDevSection3Text: \"We do not impose any limitations on what a customer-specific project may entail; we have developed unique solutions for emergency services, food companies, the forestry industry, and more.\",\r\n seeMore: \"+ Show more\",\r\n seeLess: \"- Show less\",\r\n addArticleToCart: \"Add article to cart\",\r\n megaMenu: \"If your company or business has specific needs and requirements, our team of designers is ready to collaborate with you and create customized solutions and products.\",\r\n examplesSpecialCharacters: \"Examples of special characters: \",\r\n areYouSure: \"Are you sure?\",\r\n deleteAllConfirmation: \"This will delete all products in the cart.\",\r\n exVat: \"excl. VAT\",\r\n downloadComparisonPdf: \"Download comparison as PDF\",\r\n downloadProductPdf: \"Download product attributes as PDF\",\r\n findProClip: \"Choose a ProClip for your vehicle\",\r\n findDeviceHolder: \"Find your Device Holder\",\r\n customerDetails: \"Customer details\",\r\n myPagesEmail: \"E-mail:\",\r\n refreshToContinue: \"Refresh the page to continue.\",\r\n adImageAlt: \"Work ad\",\r\n numbersOnly: \"May only contain numbers\",\r\n smsTracking: \"SMS-tracking\",\r\n cellNumber: \"Cellphone number\",\r\n homeSuctionTitle: \"Suction Cup Mounts\",\r\n homeSuctionText: \"Quick and easy mounting on smooth surfaces. Enables flexible solutions.\",\r\n homeSuctionLinkText: \"Learn more about suction cup mounts\",\r\n homeScreenTitle: \"Workstation mounts\",\r\n homeScreenText: \"Ergonomic holders for a screen and keyboard, with options for fixed or foldable holders, suited for demanding environments.\",\r\n homeScreenLinkText: \"Learn more about workstation mounts\",\r\n homeMoveClipTitle: \"MoveClip\",\r\n homeMoveClipText: \"Allows easy switching between different holders on the same mounting location, and provides the ability to conveniently use the same holder in multiple places.\",\r\n homeMoveClipLinkText: \"Learn more about MoveClip\",\r\n homeReadMoreAboutStrong: \"Read more about our stronger mounting solutions\",\r\n contactFullname: \"Full name\",\r\n contactCompany: \"Company\",\r\n contactPhone: \"Phone\",\r\n contactEmail: \"Email\",\r\n contactMessageTitle: \"How can we help you? *\",\r\n contactSend: \"Send request\",\r\n contactOfficeAndManufacturing: \"Head office and manufacturing\",\r\n contactMailSent: \"Contact request has been sent.\",\r\n newList: \"Create a new list\",\r\n productId: \"Product number\",\r\n errorCreatingFavoriteList: \"En ny lista behöver namn och produkter för att kunna skapas. A new list needs a name and at least one product to be created.\",\r\n myLists: \"My lists:\",\r\n selectLists: \"Choose lists or create a new one\",\r\n decreaseQuantity: \"Decrease quantity\",\r\n increaseQuantity: \"Increase quantity\",\r\n deleteList: \"Delete list\",\r\n editList: \"Edit list\",\r\n unlisted: \"Products not in a list\",\r\n newName: \"New name:\",\r\n selectProducts: \"Select products:\",\r\n noListIsEqualToOnlyFavorite: \"Leave empty to add to the standard list\",\r\n showUnlisted: \"Show unlisted\",\r\n showAllFavorites: \"Show all favorites\",\r\n seeProductVideo: \"Watch product video\",\r\n selectOption: \"Select an option\",\r\n textField: \"Text field\",\r\n playVideo: \"Play video\",\r\n aboutProductDevelopment: \"about our product development\",\r\n aboutProclip: \"about ProClip and Holders\",\r\n about: \"about\",\r\n previousProductImage: \"previous product image\",\r\n nextProductImage: \"next product image\",\r\n heartIcon: \"heart icon\",\r\n deleteListButton: \"delete list button\",\r\n signedInMenu: \"Signed in menu\",\r\n unavailable: \"unavailable\",\r\n cmtitle: \"\",\r\n cmmessage: \"This website uses cookies to enhance your experience.\",\r\n cmbuttonText: \"Accept\",\r\n cmdeclineButtonText: \"Decline\",\r\n cmmanageButtonText: \"Manage Cookies\",\r\n cmprivacyPolicyText: \"Privacy Policy\",\r\n cmmanageTitle: \"Cookie Preferences\",\r\n cmmanageMessage: \"Manage your cookie preferences below. Essential cookies are always enabled as they are necessary for the website to function properly.\",\r\n cmmanageEssentialTitle: \"Essential\",\r\n cmmanageEssentialSubtitle: \"Required for the website to function properly\",\r\n cmmanageEssentialStatus: \"Status: Always enabled\",\r\n cmmanageEssentialStatusButtonText: \"Always On\",\r\n cmmanageAnalyticsTitle: \"Analytics\",\r\n cmmanageAnalyticsSubtitle: \"Help us understand how visitors interact with our website\",\r\n cmmanageSocialTitle: \"Social\",\r\n cmmanageSocialSubtitle: \"Enable social media features and sharing\",\r\n cmmanageAdvertTitle: \"Advertising\",\r\n cmmanageAdvertSubtitle: \"Personalize advertisements and measure their performance\",\r\n cmmanageCookiesStatus: \"Status: {{status}} on {{date}}\",\r\n cmmanageCookiesStatusConsented: \"Consented\",\r\n cmmanageCookiesStatusDeclined: \"Declined\",\r\n cmmanageCancelButtonText: \"Cancel\",\r\n cmmanageSaveButtonText: \"Save Preferences\",\r\n consentCookiesPrompt: \"You need to consent to advertising cookies to be able to see this video\",\r\n manageConsentButtonText: \"Manage consent\"\r\n },\r\n sv: {\r\n onlyOnlineShops: \"Se enbart E-handel\",\r\n findLocalRetailer: \"Hitta din lokala återförsäljare\",\r\n viaOurDistributors: \"Brodits produkter kan köpas via våra återförsäljare.\",\r\n pdfFiles: \"PDF-filer\",\r\n compatibleProducts: \"Kompatibla modeller\",\r\n back: \"Bakåt\",\r\n showSearch: \"Visa sökfält\",\r\n hideSearch: \"Dölj sökfält\",\r\n tabInformation: \"Information\",\r\n moreInformation: \"More information\",\r\n tabSpecification: \"Specifikation\",\r\n tabCompability: \"Passar till\",\r\n tabInstructions: \"Instruktioner\",\r\n tabRelatedProducts: \"Tillbehör\",\r\n tabRelatedFiles: \"Dokument\",\r\n noRelatedFiles: \"Det finns inga dokument för den här produkten\",\r\n noAccessories: \"Det finns inga tillbehör för den här produkten\",\r\n thereAreNoVideosForThisProduct: \"Det finns inga videoklipp för den här produkten.\",\r\n itemNumber: \"Art. nr.\",\r\n loadingMaterial: \"Laddar material\",\r\n features: \"Funktioner\",\r\n fasteners: \"Fästen\",\r\n compabilities: \"Passar till följande modeller\",\r\n thisProductIsNotModelSpecific: \"Den här produkten är inte modellspecifik\",\r\n loadingCompabilities: \"Laddar kompabiliteter\",\r\n loadingProperties: \"Laddar egenskaper\",\r\n properties: \"Egenskaper\",\r\n propertiesNoneExist: \"Inga egenskaper gäller för denna produkt.\",\r\n instructions: \"Instruktioner för\",\r\n chargingSpecification: \"Laddningsspecifikationer\",\r\n error: \"Fel\",\r\n unknownErrorCreatingOrder: \"Okänt fel när ordern skapades.\",\r\n showMore: \"Visa fler\",\r\n showLess: \"Visa färre\",\r\n noMaterialsAssigned: \"Inga funktioner är knutna till den här produkten.\",\r\n comingSoon: \"Kommer snart\",\r\n loadingProduct: \"Laddar produkt\",\r\n createLeaflet: \"Skapa broschyr\",\r\n print: \"Skriv ut\",\r\n compare: \"Jämför\",\r\n isComparing: \"blir jämförd\",\r\n share: \"Dela\",\r\n loading: \"Laddar\",\r\n image: \"Bild\",\r\n addToCart: \"Lägg i varukorg\",\r\n eanNumber: \"EAN-nummer\",\r\n productInformation: \"Produktinformation\",\r\n addToFavorites: \"Lägg till som favorit\",\r\n removeFromFavorites: \"Ta bort från favoriter\",\r\n yourFavorites: \"Favoriter\",\r\n newProduct: \"Ny produkt\",\r\n pickedByPro: \"Bästsäljare\",\r\n newProductsForDevices: \"Nya produkter till enheter\",\r\n newProductsForVehicles: \"Nya produkter till fordon\",\r\n more: \"Mer\",\r\n moreSmall: \"...fler\",\r\n close: \"Stäng\",\r\n seeAll: \"Visa alla\",\r\n hits: \"träffar\",\r\n toggleLanguage: \"Växla språk\",\r\n user: \"Användare\",\r\n cart: \"Varukorg\",\r\n toggleView: \"Växla vy\",\r\n logIn: \"Logga in\",\r\n email: \"E-post\",\r\n password: \"Lösenord\",\r\n repeatPassword: \"Upprepa lösenordet\",\r\n changePassword: \"Ändra lösenord\",\r\n forgotPassword: \"Glömt lösenord\",\r\n passwordsMustMatch: \"Lösenorden måste matcha\",\r\n forgotPasswordNotification: \"Ett återställningsmail har skickats till den angivna e-posten om den finns i systemet. Länken är giltig i 30min.\",\r\n checkYourLoginDetails: \"Kontrollera dina login-uppgifter och prova igen.\",\r\n product: \"Artikel\",\r\n theProduct: \"Artikel\",\r\n hasBeenAddedToCart: \"har lagts i varukorgen\",\r\n addressDetails: \"Adressuppgifter\",\r\n confirmation: \"Bekräftelse\",\r\n yourCart: \"Din varukorg\",\r\n checkOrderDetails: \"Kontrollera din order noggrant för att vara säker på att allt stämmer.\",\r\n summary: \"Sammanställning\",\r\n numberOfOrderLines: \"Antal orderrader\",\r\n totalQuantity: \"Artiklar totalt\",\r\n total: \"Totalt\",\r\n emptyCart: \"Töm varukorg\",\r\n addNote: \"Lägg till anteckning\",\r\n note: \"Notering\",\r\n quantity: \"Order antal\",\r\n qty: \"Ant\",\r\n price: \"Pris\",\r\n backToShop: \"Tillbaka to affär\",\r\n backToCart: \"Tillbaka till varukorg\",\r\n toCheckout: \"Till kassan\",\r\n submitOrder: \"Skicka order\",\r\n myDetails: \"Mina uppgifter\",\r\n customerNumber: \"Kundnummer:\",\r\n name: \"Namn:\",\r\n messageToBrodit: \"Meddelande till Brodit\",\r\n purchaseOrder: \"Inköpsorder | Märkning\",\r\n orderPlacedBy: \"Order lagd av | Referens\",\r\n emailForOrderConfirmation: \"E-post (för orderbekräftelse)\",\r\n standardShippingAddress: \"Förvald leveransadress\",\r\n billingAddress: \"Fakturaadress\",\r\n orderConfirmation: \"Orderbekräftelse\",\r\n thankYouForOrder: \"Tack för att du beställer från Brodit!\",\r\n orderIsProcessing: \"Din order behandlas. Du kommer få en bekräftelse via e-post snart.\",\r\n orderNumber: \"Ordernummer\",\r\n orderDate: \"Orderdatum\",\r\n orderEmail: \"E-post för order\",\r\n shippingAddress: \"Leveransadress\",\r\n reference: \"Referens\", // Kanske inte nödvändig, ett datafält egentligen\r\n shop: \"Handla\",\r\n shopViaReseller: \"Du kan köpa Brodits produkter via återförsäljare\",\r\n findReseller: \"Hitta återförsäljare\",\r\n becomeReseller: \"Bli återförsäljare\",\r\n new: \"Nyhet\",\r\n news: \"Nyheter\",\r\n showMoreNews: \"Äldre nyheter\",\r\n couldNotFindTheSelectedNewsArticle: \"Kunde inte hitta den valda nyhetsartikeln\",\r\n newHolders: \"Nya hållare\",\r\n newProclip: \"Nya ProClip\",\r\n newsLetter: \"Nyhetsbrev\",\r\n aboutBrodit: \"Om Brodit\",\r\n broditsStory: \"Historien om Brodit\",\r\n broditsMovie: \"Filmen om Brodit\",\r\n cookies: \"Kakor\",\r\n values: \"Värdegrund\",\r\n policies: \"Policy\",\r\n integrityPolicy: \"Integritetspolicy\",\r\n contact: \"Kontakt\",\r\n contactBrodit: \"Kontakta Brodit\",\r\n hello: \"Hej\",\r\n contactBroditVia: \"Kontakta Brodit via \",\r\n ifYouWantToChangeAnyInformation: \" om du vill ändra någon information.\",\r\n hereIsYourUserInfo: \"Här hittar du information kring din användare.\",\r\n workAtBrodit: \"Jobba på Brodit\",\r\n findBrodit: \"Hitta till Brodit\",\r\n noArticlesInCart: \"Du har inga artiklar i varukorgen.\",\r\n yourOrders: \"Mina beställningar\",\r\n yourReference: \"Er referens\",\r\n registered: \"Registrerad\",\r\n printed: \"Utskriven\",\r\n deliveryTimeCannotBeConfirmed: \"Leveranstid kan ej bekräftas\",\r\n processing: \"Bearbetas\",\r\n partiallyDelivered: \"Delvis skickad\",\r\n deliveryComplete: \"Skickad\",\r\n date: \"Datum\",\r\n order: \"Beställning\",\r\n orderWasPlaced: \"Ordern är lagd, vänligen kontrollera din e-post efter orderbekräftelsen.\",\r\n status: \"Status\",\r\n track: \"Spåra\",\r\n marking: \"Märkning\",\r\n numberOfProducts: \"Antal produkter\",\r\n trackShipment: \"Spåra leverans\",\r\n backToOrderList: \"Tillbaka till orderlistan\",\r\n sentQuantity: \"Skickat antal\",\r\n anErrorOccuredTryRelogging: \"Ett fel inträffade. Testa att logga in på nytt.\",\r\n phone: \"Telefon\",\r\n fax: \"Fax\",\r\n published: \"Publicerad\",\r\n showImages: \"Visa mer bilder\",\r\n toggleSortOrder: \"Växla sorteringsordning\",\r\n sort: \"Sortera på\",\r\n searchOnDevice: \"Välj enhet\",\r\n searchOnVehicle: \"Välj fordon\",\r\n searchOnModel: \"Välj Modell\",\r\n searchOnModelYears: \"Välj år\",\r\n device: \"Enhet\",\r\n vehicle: \"Fordon\",\r\n howToInstall: \"Så monterar du\",\r\n thisSiteUsesCookies: \"Denna webbplats använder Cookies.\",\r\n readMore: \"Läs mer\",\r\n readMoreInThePrivacyPolicy: \"Läs mer i vår integritetspolicy.\",\r\n iAccept: \"Jag accepterar\",\r\n IHaveReadAndAcceptTheTerms: \"Jag har läst och godkänner villkoren.\",\r\n iHaveReadAndAgreeTo: \"Jag har tagit del av och accepterat\",\r\n broditABsConditionsAndTermsOfSale: \"Brodit ABs försäljningsvillkor\",\r\n information: \"Information\",\r\n companyAdress: \"Företag\",\r\n purchase: \"Inköp\",\r\n delivery: \"Leveransadress\",\r\n validate: \"Validera\",\r\n cancel: \"Avbryt\",\r\n backwards: \"Tillbaka\",\r\n next: \"Nästa\",\r\n companyName: \"Företagsnamn\",\r\n organisationNumber: \"Organisationnummer\",\r\n website: \"Hemsida\",\r\n contactPerson: \"Kontaktperson\",\r\n phonenumber: \"Telefonnummer\",\r\n streetAddress: \"Gatuadress\",\r\n postalCode: \"Postnr\",\r\n town: \"Ort\",\r\n boxDeliveryAddress: \"Boxadress\",\r\n deliveryAddress: \"Leveransadress\",\r\n postalAddress: \"Postadress\",\r\n companySignatory: \"Firmatecknare\",\r\n attachUpToDateRegistrationCertificateFromBolagsverketAsAFile: \"Bifoga aktuellt registreringsbevis från Bolagsverket (PRV) som fil i PDF-format.\",\r\n chooseAFile: \"Välj fil\",\r\n noFileHasBeenSelected: \"Ingen fil har valts.\",\r\n pleaseAcceptTheTermsAndConditionsAboveToContinue: \"Vänligen acceptera vilkoren ovan för att fortsätta.\",\r\n pleaseFillInThisCheckBox: \"Vänligen fyll i denna kryssrutan.\",\r\n sendApplication: \"Skicka ansökan\",\r\n forParcelDelivery: \"För paketleverans\",\r\n forInvoiceThroughPdfBroditOnlySendsInvoicesThroughEmail: \"för faktura via PDF (Brodit skickar endast faktura via E-post)\",\r\n yourApplicationHasBeenSent: \"Din ansökan har skickats.\",\r\n aProblemOccuredWhileProccessingYourApplication: \"Ett problem uppstod när din ansökan skulle behandlas.\",\r\n pleaseTryAgainLaterOrContactBroditsSupportIfTheProblemPersists: \"Vänligen försök igen senare eller kontakta Brodit ifall problemet kvarstår.\",\r\n couldNotConnectToTheServer: \"Det gick inte att ansluta till servern.\",\r\n aProblemOccuredWhileProccessingYourApplicationPleaseTryAgainLaterOrContactBroditsSupportIfTheProblemPersists: \"Ett problem uppstod när din ansökan skulle behandlas. Vänligen försök igen senare eller kontakta Brodits support ifall problemet kvarstår.\",\r\n models: \"Modell\",\r\n modelYears: \"Årsmodell\",\r\n otherModels: \"Övriga modeller\",\r\n products: \"Produkter\",\r\n allProducts: \"Alla produkter\",\r\n loadMore: \"Ladda fler\",\r\n searchResults: \"Sökresultat\",\r\n youSearchedFor: \"Du sökte efter\",\r\n search: \"Sök\",\r\n searchUpperCase: \"SÖK\",\r\n searchForProducts: \"Sök efter produkter\",\r\n premiereNewOnlineShop: \"Premiär ny webshop\",\r\n beforeYouLogInInfo: \"Uppdaterad shop kräver uppdaterat lösenord! Återställ ditt lösenord innan du loggar in första gången (använd funktionen nedan). Tack!\",\r\n returnNote: \"Retursedel\",\r\n logOut: \"Logga ut\",\r\n year: \"År\",\r\n chooseYear: \"Välj år\",\r\n deselectAll: \"AVMARKERA ALLA\",\r\n showOrHideFilters: \"Visa eller dölj filter\",\r\n yourEmail: \"Din e-post\",\r\n yourName: \"Ditt namn\",\r\n receiversEmail: \"Mottagarens e-post\",\r\n message: \"Meddelande\",\r\n shareThis: \"Dela detta\",\r\n orderByFile: \"Order via fil\",\r\n orderByFileInfoParagraph1: \"För enklare orderläggning kan du läsa in en orderfil i vår webshop. Du kan exportera filen från ditt eget system, och ladda upp den direkt i din varukorg så slipper du knappa in ordern manuellt. Snabbt och bekvämt!\",\r\n orderByFileInfoParagraph2: \"Specifikationer: Filen skall vara en kommaseparerad textfil. Det enklaste är att välja att spara filen i csv-format i Excel eller liknande progam, men vilken textfil som helst fungerar så länge siffrorna är avgränsade med komma eller semikolon. Filen ska endast innehålla artikelnummer och antal (Kolumn A: Artikelnummer, Kolumn B: Antal).\",\r\n upload: \"Ladda upp\",\r\n clearYourCartFirst: \"Du har redan artiklar i varukorgen. Vänligen rensa den innan du fortsätter.\",\r\n orderWasImported: \"Ordern är nu importerad till varukorgen.\",\r\n errorReadingOrderFile: \"Det uppstod ett fel när orderfilen lästes in. Försök med en annan fil.\",\r\n clear: \"Rensa\",\r\n chosenFile: \"Vald fil\",\r\n notIncludedArticlesMessage: \"Följande artiklar kunde inte hittas eller är inte till försäljning\",\r\n couldNotBePlacedInCart: \"kunde inte läggas i varukorgen, den är inte till salu eller finns inte\",\r\n yourPasswordHasBeenChanged: \"Ditt lösenord har ändrats.\",\r\n ifYouHaveProblemsWithYourCartResetIt: \"Om du har problem med varukorgen kan du klicka här för att återställa den.\",\r\n youHaveSharedTheProduct: \"Du har delat produkten.\",\r\n somethingWentWrongWhenSharingProduct: \"Någonting gick fel när produkten skulle delas.\",\r\n recaptchaError: \"Någonting gick fel med Recaptcha.\",\r\n unknownError: \"Ett okänt fel uppstod.\",\r\n articleCouldNotBeAddedQuantityZero: \"Artikeln kan inte läggas till med noll i antal.\",\r\n experiencingProblemsWithCart: \"Upplever du problem med varukorgen? \",\r\n clickHere: \"Klicka här\",\r\n toResetYourCart: \" för att återställa (tömma) den.\",\r\n endingSoon: \"Utgående\",\r\n chooseCity: \"VÄLJ STAD\",\r\n shopOnline: \"Handla online\",\r\n notFound: \"Sidan hittas inte\",\r\n thisPageWasNotFoundGoBackTo: \"Sidan kunde inte hittas. Gå till \",\r\n home: \"Specialisten på monteringsplattformar!\",\r\n phasingOut: \"Få kvar\",\r\n brands: \"Märke\",\r\n showAmount: \"Visa antal\",\r\n yourSearchGenerated: \"Din sökning genererade\",\r\n account: \"Konto\",\r\n fileDownload: \"Filnedladdning\",\r\n yourAccount: \"Mitt konto\",\r\n language: \"Språk\",\r\n english: \"Engelska\",\r\n swedish: \"Svenska\",\r\n german: \"Tyska\",\r\n includePrices: \"Inkludera priser\",\r\n updatesOnly: \"Endast uppdateringar\",\r\n newItems: \"Nya produkter\",\r\n changedItems: \"Ändrade produkter\",\r\n deletedItems: \"Borttagna produkter\",\r\n isDeleted: \"Är borttagna\",\r\n isDiscontinuedAndNoLongerAvailable: \"har utgått ur sortimentet\",\r\n removeAll: \"Ta bort alla\",\r\n removeItem: \"Ta bort produkt\",\r\n youMustChooseAType: \"Du måste välja en typ av data.\",\r\n formatShouldBeISO8601: \"Formatet måste vara YYYY-MM-DD.\",\r\n download: \"Ladda ner\",\r\n errorWhenAttemptingToDownloadFile: \"Ett fel uppstod då filen skulle laddas ner.\",\r\n type: \"Typ\",\r\n noContentForTheSelectedLanguage: \"Inget innehåll för det valda språket.\",\r\n fromDate: \"Från datum\",\r\n webshopForBroditResellers: \"Webshop för Brodits återförsäljare\",\r\n continueShopping: \"Fortsätt handla\",\r\n toSellBroditProducts: \"Att sälja Brodits produkter\",\r\n retailerApplicationText: `Brodit representeras i hela Sverige av kunniga och uppskattade återförsäljare.\r\n Om du brinner för service, kvalitet, problemlösning och vill arbeta aktivt med\r\n Brodits produkter, fyll gärna i dina uppgifter nedan så kontaktar vi dig. Tack!`,\r\n thisProductIsNotAvailableOrder: \"Den här produkten är med på din order men du kan endast se artikelnumret, du kan inte se produktens namn eller vad den passar till.\",\r\n country: \"Land\",\r\n useTemporaryAddress: \"Skicka denna order till en tillfällig leveransadress. Kostnad 35 kr exkl moms.\",\r\n zipAndCity: \"Postnummer och ort\",\r\n address: \"Adress\",\r\n productNotFound: \"Produkten hittades inte\",\r\n weCouldNotFindThisProductEtc: \"Vi kunde inte hitta den här produkten. Produkten finns inte.\",\r\n forInstanceKarlsborg: \"T.ex. \\\"54634 Karlsborg\\\"\",\r\n asLoggedInUserYouCanWithdraw: \"Som inloggad användare kan du när som helst ångra ditt samtycke genom länken i din profil eller på sidan Integritet under Dokument.\",\r\n ifYouWantToWithdrawConsent: \"Om du vill ångra ditt samtycke till cookies kan du klicka \",\r\n here: \"här\",\r\n youMustThenAcceptTheTermsAgain: \"Du måste då åter acceptera villkoren för att kunna använda sidan i inloggat läge.\",\r\n tryResettingPasswordAgain: \"Det verkar som länken inte stämmer. Försök återställa ditt lösenord igen.\",\r\n fileDownloadIsNotAvailable: \"Filnedladdning är under utveckling och är därför inte tillgängligt just nu.\",\r\n displaying: \"Visar\",\r\n outOf: \"av\",\r\n results: \"resultat\",\r\n apiKey: \"API nyckel\",\r\n badRequestFileDownload: \"Fel i indata vid filnedladdning. Är API-nyckeln i korrekt format?\",\r\n unAuthorizedFileDownload: \"Fel vid verifiering av API-nyckel. Kontrollera med Brodit att du är behörig för filnedladdning.\",\r\n compareProducts: \"Jämför produkter\",\r\n noProductsToCompare: \"Inga artiklar har lagts till i jämförelse\",\r\n description: \"Beskrivning\",\r\n placement: \"Placering\",\r\n fitsFor: \"Passar till\",\r\n technicalInformation: \"Teknisk information\",\r\n dimensionsAndWeight: \"Dimensioner & vikt\",\r\n width: \"Bredd\",\r\n height: \"Höjd\",\r\n depth: \"Djup\",\r\n weight: \"Vikt\",\r\n volume: \"Volym\",\r\n yes: \"Ja\",\r\n no: \"Nej\",\r\n compareMaxThreeArticles: \"Du kan jämföra upp till tre artiklar samtidigt.\",\r\n compareMaxTwoArticles: \"Du kan endast jämföra två artiklar samtidigt.\",\r\n toComparison: \"Till jämförelsen\",\r\n notApplicable: \"Inte tillämpbar\",\r\n clearAllProducts: \"Rensa alla produkter\",\r\n endComparison: \"Avsluta jämförelse\",\r\n thisProductIsNoLongerAvailable: \"Denna produkt är inte längre tillgänglig.\",\r\n parcel: \"Försändelse\",\r\n orderSystemMaintenance: \"Vårt ordersystem underhålls för närvarande. Under denna tid kan du inte logga in och använda vissa tjänster på webbplatsen. Uppdatera sidan om ett tag och försök igen. Vi beklagar om detta orsakar problem.\",\r\n systemMaintenanceTryAgainLater: \"För närvarande systemunderhåll, prova igen senare.\",\r\n theProductWasReplacedWithFollowingProductProducts: \"Produkten är ersatt med följande produkt(er).\",\r\n wasReplacedByFollowingArticles: \" har blivit ersatt av följande artiklar.\",\r\n itWasReplacedByTheFollowingArticles: \"Den är ersatt av följande artiklar: \",\r\n action: \"Åtgärd\",\r\n register: \"Prenumerara\",\r\n unregister: \"Avprenumerera\",\r\n save: \"Spara\",\r\n yourSubscriptionHasBeenUpdated: \"Din nyhetsprenumeration har uppdaterats.\",\r\n somethingWentWrong: \"Någonting gick fel.\",\r\n whereCanIBuy: \"Var kan jag köpa?\",\r\n thePasswordMustAlsoComplyToTheFollowingRules: \"Lösenorder måste uppfylla följande krav: \",\r\n containMinimumSixCharacters: \"Innehålla minst sex tecken\",\r\n containUpperCaseCharacters: \"Innehålla versaler\",\r\n containLowerCaseCharacters: \"Innehålla gemener\",\r\n containANumber: \"Innehålla en siffra\",\r\n containAFigure: \"Innehålla minst ett specialtecken\",\r\n productIsNotAvailable: \"Produkten finns inte tillgänglig\",\r\n withdrawingCookiesConsent: \"Ångrar samtycke till cookies...\",\r\n redirectingToStartPage: \"Omdirigeras till startsidan...\",\r\n video: \"Video\",\r\n startPage: \"startsidan\",\r\n maximum30Letters: \"Det här fältet kan innehålla maximalt 30 tecken.\",\r\n downloadCatalog: \"Ladda ner katalog\",\r\n homeSection1Titel: \"Modellspecifik tvådelslösning\",\r\n homeSection1Text: \"Våra ProClip och enhetshållare är tillverkade modellspecifikt för både enhet och fordon. ProClip monteras naturligt i interiörens springor helt utan skada eller permanenta ändringar. Sök efter vår lösning för just dina behov med hjälp av vårt sökverktyg här nedan. Hittar du inte det du söker så kontakta oss så hjälper vi dig vidare.\",\r\n findRightProclip: \"Hitta rätt ProClip för din bil\",\r\n findRightHolder: \"Hållare för din enhet\",\r\n homeSection2Titel: \"Starkare monteringslösningar\",\r\n homeSection2Text: \"Använder du en surfplatta, streckkodsläsare, betalterminal eller annan mobil enhet som behöver monteras i en truck, entreprenadmaskin eller lastbil? Vi har en lösning för alla dina behov! Med vårt breda sortiment erbjuder vi anpassade lösningar för alla typer av miljöer. Oavsett om det är på kontoret, lagret eller i luften så säkerställer vi att dina enheter alltid är inom räckhåll, även under de mest utmanande förhållandena.\",\r\n homeSectionPedestalHolderTitel: \"Piedestalfästen\",\r\n homeSectionPedestalHolderText: \"Modulärt, lättviktigt och mycket starkt. - Det är vårt sortiment av aluminiumpiedestaler för montering av tyngre enheter vid vardagligt bruk i krävande miljöer.\",\r\n homeSectionPedestalHolderLinkText: \"Mer om piedestalfästen\",\r\n homeSectionPipeHolderTitel: \"Rörfästen\",\r\n homeSectionPipeHolderText: \"Robusta rörfästen som enkelt monteras på rör och stänger. Användningsområdena är många. Lastbilar, truckar, vagnar, båtar och flygplan är exempel på där de används.\",\r\n homeSectionPipeHolderLinkText: \"Mer om rörfästen\",\r\n homeSectionTruckHolderTitel: \"Truckfästen\",\r\n homeSectionTruckHolderText: \"Lagermiljöer innefattar ofta tung utrustning och krävande förhållanden. För enhetsmontering i dessa miljöer krävs rejäla fästen som klarar av påfrestningar och vibrationer.\",\r\n homeSectionTruckHolderLinkText: \"Mer om truckfästen\",\r\n homeSectionCustomSolutionsTitel: \"Skräddarsydda lösningar\",\r\n homeSectionCustomSolutionsText: \"I vår fabrik i Karlsborg sker både utveckling och tillverkning. Om ditt företag eller din verksamhet har särskilda behov och krav så är vårt team av konstruktörer redo för att samarbeta med er och skapa skräddarsydda lösningar och produkter.\",\r\n howIsItMade: \"Såhär går det till\",\r\n homeSection4Text: \"Marknaden introducerar dagligen nya fordon och enheter. Vi har under fyra decennier rustat oss med den kunskap och det nätverk som krävs för att snabbt utveckla, tillverka och leverera produkter till en marknad som är i ständig förändring.\",\r\n deviceHolder: \"Enhetshållare\",\r\n proclip: \"ProClip\",\r\n seeProduct: \"Visa produkt\",\r\n homeSection5Title: \"Behöver du hjälp med att hitta rätt produkter?\",\r\n homeSection5Text: \"Kontakta oss och beskriv dina behov så hjälper vi dig att hitta den bästa lösningen för just dig!\",\r\n proclipAndHolders: \"ProClip och Enhetshållare\",\r\n proclipSection1Title: \"Modellspecifika ProClipfästen och enhetshållare\",\r\n proclipSection1Text: \"Vår tvådelade monteringslösning ger dig en skräddarsydd enhetsmontering som passar perfekt för dina behov. Ena delen är en enhetshållare skapad för att passa just din mobil, surfplatta eller annan handhållen enhet, denna kombineras med en ProClip som är ett fäste byggt specifikt för din bilmodel. ProClip monteras i bilen helt utan skruv och gör därmed ingen skada på interiören. Flexibelt, stabilt och säkert - Enkelt!\",\r\n proclipSection2ProclipText: \"ProClipen är monteringsplattformen för enhetshållaren, syftet med vår ProClip är att kunna montera enhetshållaren i fordonet stabilt och säkert, helt utan att göra permanenta ändringar i bilen så som att borra och skruva i instrumentpanelen. En ProClip klickas istället fast i bilens befintliga springor, paneler eller skarvar på instrumentbrädan. I många fall säkras den sedan av en dubbelhäftande tejp som är speciellt framtagen för att inte lämna några spår efter sig om man vill ta ur eller flytta en ProClip. En ProClip är framtagen specifikt för varje bil- och årsmodell och framtagningen av en ny ProClip är ett hantverk om görs på plats i varje bil och lastbil. Oftast tar vi fram ett par ProClip till varje fordonsmodell för att kunna erbjuda en rad olika placeringar att välja mellan.\",\r\n proclipSection2HolderTitle: \"Enhetshållare\",\r\n proclipBrandsTitle: \"Vi erbjuder ProClip för fordon från ett brett urval av märken, bland annat:\",\r\n deviceBrandsTitle: \"Vi erbjuder hållare för enheter från ett brett urval av varumärken, bland annat:\",\r\n proclipSection2HolderText: \"Enhetshållaren är också designad specifikt för din smartphone, GPS eller annan mobil enhet. Olika val erbjuds utifrån om du har enheten med eller utan skal, önskar laddning med kabel eller trådlöst eller en passiv hållare om du inte önskar laddning. Utöver våra modellspecifika enhetshållare erbjuder vi även justerbara hållare som kan anpassas i höjd eller bredd beroende på vilken enhet du vill använda den till.\",\r\n proclipSection3ProclipBrands: \"ProClip finns för alla dessa fordonsmärkena\",\r\n proclipSection3ProclipDevices: \"Vi har Enhetshållare för bland annat dessa varumärken\",\r\n productDevSection1Title: \"Skräddarsydda lösningar\",\r\n productDevSection1Text: \"I de fall då vårt befintliga sortiment inte räcker för att tillgodose kundens behov, har vi möjlighet att skapa en skräddarsydd monteringslösning.\",\r\n productDevSection2Title: \"Behovsanalys\",\r\n productDevSection2TextPart1: \"Processen inleds med en direkt kommunikation mellan dig, våra säljare och produktutvecklare. Tillsammans identifierar vi behov och potentiella lösningar.\",\r\n productDevSection2TextPart2: \" Behoven kan variera beroende på hur och var enheten ska användas. Dessa behov inkluderar faktorer som tuffa miljöer, tekniska specifikationer, laddnings- och dataöverföringskrav med mera.\",\r\n productDevSection2Part3Title: \"Kostnadsuppskattning och prototyp\",\r\n productDevSection2TextPart3: \"När vi har uppnått en gemensam bild av hur produkten ska utformas presenterar vi en utvecklingskostnad. Om denna kostnad godkänns så går vi vidare med att tillverka en prototyp. Prototypen kan vara en skarp, CNC-bearbetad version eller i vissa fall, en 3D-utskriven prototyp.\",\r\n contactUs: \"Kontakta oss\",\r\n productDevSection3Text: \"Vi sätter inga begränsningar på vad ett kundspecifikt projekt kan innebära, vi har tagit fram unika lösningar till både blåljusverksamhet, livsmedelsföretag, skogsindustrin med mera.\",\r\n seeMore: \"+ Visa fler\",\r\n seeLess: \"- Visa färre\",\r\n addArticleToCart: \"Lägg till artikel\",\r\n megaMenu: \"Om ditt företag eller din verksamhet har särskilda behov och krav så är vårt team av konstruktörer redo för att samarbeta med er och skapa skräddarsydda lösningar och produkter.\",\r\n examplesSpecialCharacters: \"Exempel på specialtecken: \",\r\n areYouSure: \"Är du säker?\",\r\n deleteAllConfirmation: \"Detta kommer ta bort alla produkter i varukorgen.\",\r\n exVat: \"exkl. moms\",\r\n downloadComparisonPdf: \"Ladda hem jämförelse som PDF\",\r\n downloadProductPdf: \"Ladda hem produkt attribut as PDF\",\r\n findProClip: \"Välj en ProClip till ditt fordon\",\r\n findDeviceHolder: \"Hitta din enhetshållare\",\r\n customerDetails: \"Kunduppgifter\",\r\n myPagesEmail: \"E-post:\",\r\n refreshToContinue: \"Ladda om sidan för att fortsätta.\",\r\n adImageAlt: \"Jobb annons\",\r\n numbersOnly: \"Får endast innehålla siffror\",\r\n smsTracking: \"SMS-avisering\",\r\n cellNumber: \"Mobilnummer\",\r\n homeSuctionTitle: \"Sugproppsfästen\",\r\n homeSuctionText: \"Snabb och enkel montering på släta ytor. Möjliggör flexibla lösningar.\",\r\n homeSuctionLinkText: \"Mer om sugproppsfästen\",\r\n homeScreenTitle: \"Skärm och Tangentbordshållare\",\r\n homeScreenText: \"Ergonomiska hållare för skärm och tangentbord, med alternativ för fast eller vikbar hållare, anpassade för krävande miljöer.\",\r\n homeScreenLinkText: \"Mer om skärm och tangentbordshållare\",\r\n homeMoveClipTitle: \"MoveClip\",\r\n homeMoveClipText: \"Möjliggör enkla byten mellan olika hållare på samma monteringsplats, samt ger möjlighet att smidigt använda samma hållare på flera platser.\",\r\n homeMoveClipLinkText: \"Mer om MoveClip\",\r\n homeReadMoreAboutStrong: \"Läs mer om vårt starkare sortiment\",\r\n contactFullname: \"För- och efternamn\",\r\n contactCompany: \"Företag\",\r\n contactPhone: \"Telefon\",\r\n contactEmail: \"Epost\",\r\n contactMessageTitle: \"Vad kan vi hjälpa dig med? *\",\r\n contactSend: \"Skicka förfrågan\",\r\n contactOfficeAndManufacturing: \"Huvudkontor och tillverkning\",\r\n contactMailSent: \"Kontaktförfrågan har skickats.\",\r\n newList: \"Skapa en ny favoritlista\",\r\n productId: \"Artikelnummer\",\r\n errorCreatingFavoriteList: \"En ny lista behöver namn och produkter för att kunna skapas.\",\r\n myLists: \"Mina listor:\",\r\n selectLists: \"Välj listor eller skapa en ny\",\r\n decreaseQuantity: \"Minska antal\",\r\n increaseQuantity: \"Öka antal\",\r\n deleteList: \"Ta bort lista\",\r\n editList: \"Redigera lista\",\r\n unlisted: \"Artiklar ej i lista\",\r\n newName: \"Nytt namn:\",\r\n selectProducts: \"Välj produkter:\",\r\n noListIsEqualToOnlyFavorite: \"Lämna tom för att lägga till i standardad listan\",\r\n showUnlisted: \"Visa olistade\",\r\n showAllFavorites: \"Visa alla favoriter\",\r\n seeProductVideo: \"Se produktfilm\",\r\n selectOption: \"Select an option\",\r\n textField: \"Textfält\",\r\n playVideo: \"Spela video\",\r\n aboutProductDevelopment: \"om vår produkt utveckling\",\r\n aboutProclip: \"om ProClip och hållare\",\r\n about: \"om\",\r\n previousProductImage: \"förra produkt bild\",\r\n nextProductImage: \"nästa produkt bild\",\r\n heartIcon: \"hjärtsymbol\",\r\n deleteListButton: \"radera lista\",\r\n signedInMenu: \"inloggad meny\",\r\n unavailable: \"ej tillgänglig\",\r\n cmtitle: \"\",\r\n cmmessage: \"Denna webbplats använder cookies för att förbättra din upplevelse.\",\r\n cmbuttonText: \"Acceptera\",\r\n cmdeclineButtonText: \"Avböj\",\r\n cmmanageButtonText: \"Hantera cookies\",\r\n cmprivacyPolicyText: \"Integritetspolicy\",\r\n cmmanageTitle: \"Cookie-inställningar\",\r\n cmmanageMessage: \"Hantera dina cookie-inställningar nedan. Nödvändiga cookies är alltid aktiverade eftersom de krävs för att webbplatsen ska fungera korrekt.\",\r\n cmmanageEssentialTitle: \"Nödvändiga\",\r\n cmmanageEssentialSubtitle: \"Krävs för att webbplatsen ska fungera korrekt\",\r\n cmmanageEssentialStatus: \"Status: Alltid aktiverad\",\r\n cmmanageEssentialStatusButtonText: \"Alltid på\",\r\n cmmanageAnalyticsTitle: \"Analys\",\r\n cmmanageAnalyticsSubtitle: \"Hjälper oss att förstå hur besökare interagerar med vår webbplats\",\r\n cmmanageSocialTitle: \"Sociala\",\r\n cmmanageSocialSubtitle: \"Aktivera funktioner för sociala medier och delning\",\r\n cmmanageAdvertTitle: \"Annonsering\",\r\n cmmanageAdvertSubtitle: \"Anpassa annonser och mäta deras prestanda\",\r\n cmmanageCookiesStatus: \"Status: {{status}} den {{date}}\",\r\n cmmanageCookiesStatusConsented: \"Godkänt\",\r\n cmmanageCookiesStatusDeclined: \"Avböjt\",\r\n cmmanageCancelButtonText: \"Avbryt\",\r\n cmmanageSaveButtonText: \"Spara inställningar\",\r\n consentCookiesPrompt: \"Du måste samtycka till cookies innan du kan se denna video.\",\r\n manageConsentButtonText: \"Hantera samtycke\"\r\n }\r\n})\r\n","// Need to use the React-specific entry point to import createApi\r\nimport { addPrices } from \"../priceSlice\"\r\nimport { createApi, fetchBaseQuery } from \"@reduxjs/toolkit/query/react\"\r\n\r\nexport const priceApi = createApi({\r\n reducerPath: \"priceApi\",\r\n baseQuery: fetchBaseQuery({ baseUrl: \"/api/ProductInfo/\" }),\r\n endpoints: builder => ({\r\n getPrices: builder.query({\r\n query: ({ authToken, ids }) => ({\r\n url: \"GetPrices\",\r\n method: \"POST\",\r\n body: {\r\n authToken,\r\n ids\r\n }\r\n }),\r\n\r\n async onQueryStarted({ _authToken, _ids }, { dispatch, queryFulfilled }) {\r\n try {\r\n const { data, meta } = await queryFulfilled\r\n\r\n if (meta.response.status === 200) {\r\n dispatch(addPrices(data))\r\n } else {\r\n console.warn(`Unexpected status code: ${meta.response.status}`)\r\n }\r\n } catch (err) {\r\n if (err?.error?.status) {\r\n console.error(`Request failed with status ${err.error.status}`)\r\n } else {\r\n console.error(\"Error fetching prices:\", err)\r\n }\r\n }\r\n }\r\n })\r\n })\r\n})\r\n\r\nexport const { useGetPricesQuery } = priceApi\r\n","import { prepareProducts } from \"../../components/CompareProducts/helperFunctions\"\r\nimport { replaceNameForBrandOther, restoreNameForBrandOther, sortBrands } from \"../../lib/helper/brandHelper\"\r\nimport { filterFaultyValues, isSearchQueryEmpty } from \"../../lib/helper/searchHelper\"\r\nimport { createApi, fetchBaseQuery } from \"@reduxjs/toolkit/query/react\"\r\n\r\nexport const productInfoApi = createApi({\r\n reducerPath: \"productInfoApi\",\r\n baseQuery: fetchBaseQuery({ baseUrl: \"/api/ProductInfo/\" }),\r\n endpoints: builder => ({\r\n getBrands: builder.query({\r\n query: ({ language, steering = null }) => (\r\n `GetBrands?language=${language}${steering ? `&steering=${steering}` : \"\"}`\r\n ),\r\n transformResponse: response => {\r\n const nameCorrectedBrands = replaceNameForBrandOther(response)\r\n const sortedBrands = sortBrands(nameCorrectedBrands)\r\n return sortedBrands\r\n }\r\n }),\r\n getProductsByFilter: builder.query({\r\n query: ({ filters, pagination, language }) => {\r\n // Filter out empty search keywords.\r\n const cleanFilters = filterFaultyValues(filters)\r\n\r\n // Prevent fetching when filter is empty.\r\n const isEmpty = isSearchQueryEmpty(cleanFilters)\r\n if (isEmpty) return null\r\n\r\n // Restore the original name of the \"Other models\" brand.\r\n if (cleanFilters.brands) {\r\n cleanFilters.brands = restoreNameForBrandOther(cleanFilters.brands)\r\n }\r\n return {\r\n url: \"GetProductsByFilter\",\r\n method: \"POST\",\r\n body: { ...cleanFilters, ...pagination, language }\r\n }\r\n },\r\n transformResponse: (response, _meta, arg) => {\r\n const productList = response?.pagedList?.response?.list ?? []\r\n const products = prepareProducts(productList, arg.language)\r\n return {\r\n ...response,\r\n products: products,\r\n brands: replaceNameForBrandOther(response.brands)\r\n }\r\n }\r\n }),\r\n getModelYears: builder.query({\r\n query: args => ({\r\n url: \"GetModelYears\",\r\n method: \"POST\",\r\n body: {\r\n brandIds: [args.brand],\r\n modelIds: [args.model],\r\n language: args.language,\r\n steering: [args.steering]\r\n }\r\n }),\r\n transformResponse: response => response.response\r\n })\r\n })\r\n})\r\n\r\nexport const { useGetBrandsQuery, useGetProductsByFilterQuery, useGetModelYearsQuery } = productInfoApi\r\n","/* eslint-disable import/prefer-default-export */\r\nexport const selectDynamicPage = (pageList, id) => pageList.filter(page => page.id === id)?.[0]\r\nexport const selectMarkdownText = (dynamicPage, language) => dynamicPage?.markdown?.filter(markdown => markdown.lang === language)?.[0]?.text\r\n","// Need to use the React-specific entry point to import createApi\r\nimport { selectDynamicPage, selectMarkdownText } from \"../../lib/helper/dynamicContentHelper\"\r\nimport { createApi, fetchBaseQuery } from \"@reduxjs/toolkit/query/react\"\r\n// import { sortNews } from '../../lib/helper/newsHelper';\r\n\r\n// Define a service using a base URL and expected endpoints\r\nexport const contentApi = createApi({\r\n reducerPath: \"contentApi\",\r\n baseQuery: fetchBaseQuery({ baseUrl: \"/files/\" }),\r\n endpoints: builder => ({\r\n // getProclipNews: builder.query({\r\n // query: () => `news/proclip.json`,\r\n // transformResponse: (response) => sortNews(response),\r\n // }),\r\n getContent: builder.query({\r\n query: route => `${route}`\r\n }),\r\n getDynamicPages: builder.query({\r\n query: \"DynamicPages/DynamicPages.json\"\r\n }),\r\n getDynamicPageMarkdown: builder.query({\r\n query: () => \"DynamicPages/DynamicPages.json\",\r\n transformResponse: (response, _meta, arg) => {\r\n const dynamicPage = selectDynamicPage(response, arg.id)\r\n const markdownText = selectMarkdownText(dynamicPage, arg.language)\r\n\r\n return markdownText\r\n }\r\n }),\r\n getDynamicPage: builder.query({\r\n query: () => \"DynamicPages/DynamicPages.json\",\r\n transformResponse: (response, _meta, arg) => selectDynamicPage(response, arg.id)\r\n })\r\n })\r\n})\r\n// export const { useGetProclipNewsQuery } = contentApi;\r\nexport const {\r\n useGetContentQuery,\r\n useGetDynamicPagesQuery,\r\n useGetDynamicPageMarkdownQuery,\r\n useGetDynamicPageQuery\r\n} = contentApi\r\n","import { createAsyncThunk } from \"@reduxjs/toolkit\"\r\nimport axios from \"axios\"\r\n\r\nconst fetchCustomerOrders = async (authToken, offset, limit) => {\r\n const a = await axios.get(\r\n `/api/ProductInfo/GetCustomerOrders?authToken=${authToken}&offset=${offset}&limit=${limit}`\r\n ) // offset and limit not used in backend, only last 20 is displayed\r\n return a.data\r\n}\r\n\r\n// Fetch customer orders, but do not save them in a adapter.\r\nexport const requestCustomerOrders = createAsyncThunk(\r\n \"customerOrders/fetch\",\r\n async (params, { rejectWithValue }) => {\r\n try {\r\n const { authToken, offset, limit } = params\r\n return await fetchCustomerOrders(authToken, offset, limit)\r\n } catch (err) {\r\n return rejectWithValue(\"Could not fetch customer order.\")\r\n }\r\n }\r\n)\r\n\r\nconst fetchCustomerOrder = async (authToken, id) => {\r\n const a = await axios.get(\r\n `/api/ProductInfo/GetCustomerOrder?orderNumber=${id}&authToken=${authToken}`\r\n )\r\n return a.data\r\n}\r\n\r\nexport const requestCustomerOrder = createAsyncThunk(\r\n \"customerOrders/fetchById\",\r\n async (params, { rejectWithValue }) => {\r\n try {\r\n const { authToken, id } = params\r\n return await fetchCustomerOrder(authToken, id)\r\n } catch (err) {\r\n return rejectWithValue(\"Could not fetch customer orders.\")\r\n }\r\n }\r\n)\r\n","import { setFavoriteProducts, setShouldSyncFavorites } from \"../favoriteSlice\"\r\nimport { createApi, fetchBaseQuery } from \"@reduxjs/toolkit/query/react\"\r\nimport { batch } from \"react-redux\"\r\n\r\nexport const favoriteApi = createApi({\r\n reducerPath: \"favoriteApi\",\r\n baseQuery: fetchBaseQuery({ baseUrl: \"/api/favorite/\" }),\r\n endpoints: builder => ({\r\n\r\n getFavorite: builder.query({\r\n query: ({ authToken }) => `GetFromAuthToken?authToken=${authToken}`,\r\n // transformResponse: (response) => response?.response,\r\n\r\n async onQueryStarted({ _authToken }, { dispatch, queryFulfilled }) {\r\n // Request has started.\r\n try {\r\n const { data: favoriteFromServer } = await queryFulfilled\r\n // Request succeeded.\r\n // Batch prevents rerendering for each dispatch and\r\n // instead only rerenders once.\r\n batch(() => {\r\n dispatch(setFavoriteProducts(\r\n favoriteFromServer\r\n ))\r\n dispatch(setShouldSyncFavorites(false))\r\n })\r\n } catch (err) {\r\n // Request returned and error.\r\n }\r\n }\r\n }),\r\n\r\n updateFavorite: builder.mutation({\r\n query: ({ authToken, favorite }) => ({\r\n url: `UpdateFromAuthToken?authToken=${authToken}`,\r\n method: \"POST\",\r\n body: favorite\r\n })\r\n // transformResponse: (response) => response?.response,\r\n })\r\n })\r\n})\r\n\r\nexport const { useGetFavoriteQuery, useUpdateFavoriteMutation } = favoriteApi\r\n","import { createEntityAdapter } from \"@reduxjs/toolkit\";\r\n\r\nexport const materialAdapter = createEntityAdapter({\r\n selectId: material => material.id,\r\n sortComparer: (a, b) => a.id.localeCompare(b.id)\r\n});\r\n\r\nexport const materialSelectors = materialAdapter.getSelectors(state => state.material)\r\n\r\nexport const { selectById, selectAll } = materialSelectors;\r\n","/* eslint-disable import/prefer-default-export */\r\nimport { useParams } from \"react-router-dom\"\r\n\r\nconst useLanguage = () => {\r\n const { locale } = useParams()\r\n return locale\r\n}\r\n\r\nexport { useLanguage }\r\n","import { createEntityAdapter } from \"@reduxjs/toolkit\";\r\n\r\nexport const priceAdapter = createEntityAdapter({\r\n selectId: price => price.productId\r\n});\r\n\r\nexport const priceSelectors = priceAdapter.getSelectors(state => state.price);\r\n\r\nexport const { selectById } = priceSelectors;\r\n","import { createTheme } from \"@mui/material\"\r\nimport { grey } from \"@mui/material/colors\"\r\n\r\nexport default createTheme({\r\n props: {\r\n MuiButtonBase: {\r\n disableRipple: true\r\n }\r\n },\r\n palette: {\r\n primary: {\r\n main: \"#F09057\"\r\n },\r\n secondary: {\r\n main: grey[500]\r\n },\r\n contrastThreshold: 3,\r\n background: {\r\n default: \"#fafafa\"\r\n }\r\n },\r\n typography: {\r\n body2: {\r\n fontSize: \"1rem\"\r\n }\r\n },\r\n components: {\r\n MuiInputBase: {\r\n styleOverrides: {\r\n root: {\r\n \"&.Mui-focused\": {\r\n borderColor: \"#6C6C6C\"\r\n }\r\n }\r\n }\r\n },\r\n MuiOutlinedInput: {\r\n styleOverrides: {\r\n root: {\r\n \"&.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n border: \"1px solid #2d2d2d\"\r\n }\r\n }\r\n }\r\n },\r\n MuiSelect: {\r\n styleOverrides: {\r\n select: {\r\n \"&.MuiSelect-standard\": {\r\n borderBottom: \"1px solid #2d2d2d\"\r\n }\r\n }\r\n }\r\n },\r\n MuiButton: {\r\n styleOverrides: {\r\n root: {\r\n color: \"#2d2d2d\",\r\n borderColor: \"#2d2d2d\"\r\n }\r\n }\r\n },\r\n MuiLink: {\r\n styleOverrides: {\r\n root: {\r\n color: \"#2d2d2d\",\r\n borderColor: \"#2d2d2d\",\r\n textDecorationColor: \"#2d2d2d\",\r\n fontWeight: 600\r\n }\r\n }\r\n }\r\n }\r\n})\r\n","export const microBreakpoint = 300\r\nexport const mobileBreakpoint = 769 // px\r\nexport const mobileMenuBreakpoint = 1081\r\nexport const tabletBreakpoint = 1199\r\nexport const productViewBreakpoint = 999\r\nexport const desktopBreakpoint = 1920\r\nexport const midSizeBreakpoint = 1600\r\n","import { useLanguage } from \"../../lib/hooks/languageHooks\"\r\nimport { useSelector } from \"react-redux\"\r\n\r\n// Uses the user steering setting on english website,\r\n// and defaults to LHD on swedish language.\r\nexport const useSteering = () => {\r\n const language = useLanguage()\r\n return useSelector(\r\n state => (\r\n language === \"en\"\r\n ? (state.user.steering ?? \"1\")\r\n : \"1\"\r\n )\r\n )\r\n}\r\n\r\nexport const useUser = () => useSelector(state => state.user)\r\n\r\nexport const useIsUserAuthorized = () => {\r\n const isAuthorized = useSelector(state => Boolean(state.user.authToken))\r\n const item = sessionStorage.getItem(\"isAuthorized\")\r\n\r\n return isAuthorized && !!item\r\n}\r\n\r\nexport const useUserAuthToken = () => useSelector(state => state.user.authToken)\r\n\r\nexport const useUserData = () => useSelector(state => state.user.user)\r\n\r\nexport const useSelectedModTek = () => useSelector(state => state.user.selectedModTek)\r\n","import { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nconst slice = createSlice({\r\n name: \"userMessage\",\r\n initialState: {\r\n snackPack: []\r\n },\r\n reducers: {\r\n setMessage: (state, action) => {\r\n state.snackPack.push(\r\n {\r\n message: action.payload.message,\r\n key: new Date().getTime(),\r\n severity: action.payload.severity ?? \"info\",\r\n type: action.payload.type ?? \"snackbar\",\r\n autoHide: action.payload.autoHide ?? false\r\n }\r\n )\r\n },\r\n nextSnackPack: state => {\r\n state.snackPack = state.snackPack.slice(1)\r\n }\r\n }\r\n})\r\n\r\nconst { setMessage, nextSnackPack } = slice.actions\r\n\r\nexport default slice.reducer\r\n\r\nexport const setSnackbarMessage = (message, severity) => dispatch => dispatch(\r\n setMessage({\r\n message,\r\n severity,\r\n autoHide: true,\r\n type: \"snackbar\"\r\n })\r\n)\r\n\r\nexport const setDialogMessage = message => dispatch => dispatch(\r\n setMessage({\r\n message,\r\n autoHide: false,\r\n type: \"dialog\"\r\n })\r\n)\r\n\r\nexport const setNextSnackPack = () => dispatch => dispatch(\r\n nextSnackPack()\r\n)\r\n","import { filterFaultyValues } from \"../lib/helper/searchHelper\"\r\nimport { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nconst searchSlice = createSlice({\r\n name: \"search\",\r\n reducers: {\r\n /**\r\n * Creates a new search query entry with the name of \"type\" containing\r\n * the value of \"value\".\r\n * @param {*} state The current state (using \"Immer\").\r\n * @param {object} payload An object containing two keys { type, value }.\r\n * payload.type {string} The name of the entry to create/override.\r\n * payload.value {object} The value of the search query entry.\r\n * Note: The payload.value object must follow the standard, that for each\r\n * key the value must be represented as an array, for example:\r\n * { customKeyword: [\"value1\", \"value2\", ...], anotherCustomKeyword: [\"another value\"], thirdCustomKeyword: [], ...}\r\n * Keys with faulty values, for example empty arrays and falsy values\r\n * will not be added.\r\n */\r\n setSearchQuery: (state, { payload }) => {\r\n const { type, value, clearFilter } = payload\r\n if (clearFilter) state.searchQueries = {}\r\n state.searchQueries[type] = filterFaultyValues(value)\r\n },\r\n\r\n /**\r\n * Overrides a part of a search query entry with the name of \"type\" and\r\n * spreads in the value of \"value\".\r\n * @param {*} state The current state (using \"Immer\").\r\n * @param {object} payload An object containing two keys { type, value }.\r\n * payload.type {string} The name of the entry to create/update.\r\n * payload.value {object} The value you want to spread into the\r\n * search querys existing value.\r\n * Note: The payload.value object must follow the standard, that for each\r\n * key the value must be represented as an array, for example:\r\n * { customKeyword: [\"value1\", \"value2\", ...], anotherCustomKeyword: [\"another value\"], thirdCustomKeyword: [], ...}\r\n * Keys with faulty values, for example empty arrays and falsy values\r\n * will not be added.\r\n */\r\n updateSearchQuery: (state, { payload }) => {\r\n const { type, value } = payload\r\n\r\n const newValue = {\r\n ...state.searchQueries[type],\r\n ...value\r\n }\r\n\r\n state.searchQueries[type] = filterFaultyValues(newValue)\r\n },\r\n\r\n /**\r\n * Removes all filters in the search query.\r\n * @param {*} state The current state (using \"Immer\").\r\n * @param {object} payload (Optional) An object containing the key { exclude }.\r\n * payload.exclude {Array} The search query keys specified in\r\n * this list will not be removed.\r\n */\r\n clearSearchQuery: (state, { payload }) => {\r\n if (payload?.exclude) {\r\n // Removes all keys except the excluded keys\r\n const excludedSearchQueries = Object.entries(state.searchQueries)\r\n .reduce(\r\n (prev, [key, value]) => (\r\n payload.exclude.includes(key)\r\n ? { ...prev, [key]: value }\r\n : prev\r\n ),\r\n {}\r\n )\r\n\r\n state.searchQueries = excludedSearchQueries\r\n } else {\r\n state.searchQueries = {}\r\n }\r\n }\r\n },\r\n\r\n initialState: {\r\n /**\r\n * Search query entry inside the searchQueries object should always follow\r\n * the standard of \"componentNameResponsibleForThisQuery: { customKeyword: [], anotherCustomKeyword: [], ...}\r\n */\r\n searchQueries: {\r\n // Example structure:\r\n // vehicleSearchbar: { brands: [], models: [], years: [] },\r\n // deviceSearchbar: { brands: [], models: [] },\r\n // filterProducts: { brands: [], models: [], years: [], collections: [] },\r\n }\r\n }\r\n})\r\n\r\nexport const { setSearchQuery, updateSearchQuery, clearSearchQuery } = searchSlice.actions\r\nexport default searchSlice.reducer\r\n","import { eraseCookie, loadCookie, saveCookie } from \"./cookieStorage\"\r\nimport { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nexport const userSlice = createSlice({\r\n name: \"user\",\r\n initialState: {\r\n isAuthorized: JSON.parse(sessionStorage.getItem(\"isAuthorized\")) || false,\r\n authToken: null,\r\n user: {},\r\n addresses: {},\r\n welcomeSplashVisible: false,\r\n currency: null,\r\n steering: \"1\",\r\n selectedModTek: { id: \"\", step: \"\" }\r\n },\r\n reducers: {\r\n setUser: (state, action) => {\r\n const {\r\n user, addresses, currency, welcomeSplashVisible\r\n } = action.payload\r\n const { authToken, ...userData } = user\r\n const showWelcomeSplash = welcomeSplashVisible ?? true\r\n sessionStorage.setItem(\"isAuthorized\", \"true\")\r\n saveCookie(\"user\", {\r\n authToken: authToken,\r\n welcomeSplashVisible: showWelcomeSplash\r\n })\r\n\r\n state.authToken = authToken\r\n state.user = userData\r\n state.addresses = addresses\r\n state.currency = currency\r\n state.steering = user?.preferredSteering ? user.preferredSteering.toString() : \"1\"\r\n state.welcomeSplashVisible = showWelcomeSplash\r\n state.isAuthorized = true\r\n },\r\n closeWelcomeSplash: state => {\r\n saveCookie(\"user\", { ...loadCookie(\"user\"), welcomeSplashVisible: false })\r\n state.welcomeSplashVisible = false\r\n },\r\n signOut: state => {\r\n eraseCookie(\"user\")\r\n\r\n state.authToken = null\r\n state.user = {}\r\n state.addresses = {}\r\n state.currency = null\r\n state.isAuthorized = false\r\n sessionStorage.removeItem(\"isAuthorized\")\r\n },\r\n setSteering: (state, action) => {\r\n state.steering = action.payload\r\n },\r\n setSelectedModTek: (state, action) => {\r\n state.selectedModTek = action.payload\r\n }\r\n }\r\n})\r\n\r\nexport default userSlice.reducer\r\n\r\nexport const {\r\n signOut: signOutAction,\r\n setUser,\r\n setSteering,\r\n setSelectedModTek,\r\n closeWelcomeSplash\r\n} = userSlice.actions\r\n\r\nexport const signIn = user => dispatch => dispatch(setUser(user))\r\nexport const signOut = () => dispatch => dispatch(signOutAction())\r\nexport const changeSteering = steering => dispatch => dispatch(setSteering(steering))\r\nexport const changeSelectedModTek = selected => dispatch => dispatch(setSelectedModTek(selected))\r\nexport const closeWelcome = () => dispatch => dispatch(closeWelcomeSplash())\r\n","import { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nconst slice = createSlice({\r\n name: \"productCompare\",\r\n initialState: {\r\n productIds: [],\r\n showOverview: false,\r\n onComparePage: false\r\n },\r\n reducers: {\r\n addToCompare: (state, action) => {\r\n const result = [...state.productIds, action.payload]\r\n const distinctResult = [...new Set(result)]\r\n state.productIds = distinctResult\r\n },\r\n removeFromCompare: (state, action) => {\r\n state.productIds = [...state.productIds.filter(\r\n element => element !== action.payload\r\n )]\r\n },\r\n removeAllFromCompare: state => {\r\n state.productIds = []\r\n },\r\n setShowCompareOverview: (state, action) => {\r\n state.showOverview = action.payload\r\n },\r\n setIsOnComparePage: (state, action) => {\r\n state.onComparePage = action.payload\r\n }\r\n }\r\n})\r\n\r\nexport const {\r\n addToCompare,\r\n removeFromCompare,\r\n setShowCompareOverview,\r\n removeAllFromCompare,\r\n setIsOnComparePage\r\n} = slice.actions\r\n\r\nexport default slice.reducer\r\n","import { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nconst DEFAULT_LIMIT = 20\r\nconst DEFAULT_OFFSET = 0\r\n\r\nexport const pageSlice = createSlice({\r\n name: \"page\",\r\n initialState: {\r\n limit: DEFAULT_LIMIT,\r\n offset: 0,\r\n prevLimit: DEFAULT_LIMIT,\r\n prevOffset: 0,\r\n action: \"none\",\r\n userSelectedLimit: DEFAULT_LIMIT\r\n },\r\n reducers: {\r\n increaseLimit: state => ({\r\n ...state,\r\n prevLimit: state.limit,\r\n limit: state.limit + state.userSelectedLimit,\r\n action: \"load_more\"\r\n }),\r\n reset: state => ({\r\n ...state,\r\n prevLimit: state.limit,\r\n prevOffset: state.offset,\r\n limit: DEFAULT_LIMIT,\r\n offset: DEFAULT_OFFSET,\r\n userSelectedLimit: DEFAULT_LIMIT,\r\n action: \"none\"\r\n }),\r\n savePage: state => ({\r\n ...state,\r\n prevLimit: state.limit,\r\n prevOffset: state.offset,\r\n action: \"leave\"\r\n }),\r\n setLimit: (state, action) => ({\r\n ...state,\r\n prevLimit: state.limit,\r\n prevOffset: state.offset,\r\n limit: action.payload,\r\n action: \"load_more\"\r\n }),\r\n setOffset: (state, action) => {\r\n state.action = \"load_more\"\r\n state.prevOffset = state.offset\r\n state.offset = action.payload\r\n },\r\n setUserSelectedLimit: (state, action) => {\r\n state.userSelectedLimit = action.payload\r\n }\r\n }\r\n})\r\n\r\nexport default pageSlice.reducer\r\n\r\nconst {\r\n increaseLimit, reset, savePage, setLimit, setUserSelectedLimit, setOffset\r\n} = pageSlice.actions\r\n\r\nexport const saveCurrentPage = () => dispatch => dispatch(\r\n savePage()\r\n)\r\n\r\nexport const increasePageLimit = () => dispatch => dispatch(\r\n increaseLimit()\r\n)\r\n\r\nexport const resetCurrentPage = () => dispatch => dispatch(\r\n reset()\r\n)\r\n\r\nexport const setPageLimit = limit => dispatch => dispatch(\r\n setLimit(limit)\r\n)\r\n\r\nexport const setUserLimit = limit => dispatch => dispatch(\r\n setUserSelectedLimit(limit)\r\n)\r\n\r\nexport const setPageOffset = offset => dispatch => dispatch(\r\n setOffset(offset)\r\n)\r\n","import { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nexport const settingsSlice = createSlice({\r\n name: \"settings\",\r\n initialState: {\r\n productGridView: true,\r\n proxyPath: \"\",\r\n recaptchaSiteKey: \"\",\r\n isShowingNavbarSearch: false\r\n },\r\n reducers: {\r\n toggleProductGridView: state => ({\r\n ...state,\r\n productGridView: !state.productGridView\r\n }),\r\n setPP: (state, action) => {\r\n state.proxyPath = action.payload\r\n },\r\n setRCSK: (state, action) => {\r\n state.recaptchaSiteKey = action.payload\r\n },\r\n setShowNavbarSearch: (state, action) => {\r\n state.isShowingNavbarSearch = action.payload\r\n }\r\n }\r\n})\r\n\r\nexport default settingsSlice.reducer\r\n\r\nconst {\r\n toggleProductGridView, setPP, setRCSK, setShowNavbarSearch: setShowNavbarSearchAction\r\n} = settingsSlice.actions\r\n\r\nexport const toggleProductGridViewSetting = () => dispatch => dispatch(toggleProductGridView())\r\n\r\nexport const setProxyPath = proxyPath => dispatch => dispatch(\r\n setPP(proxyPath)\r\n)\r\n\r\nexport const setRecaptchaSiteKey = sitekey => dispatch => dispatch(\r\n setRCSK(sitekey)\r\n)\r\n\r\nexport const setShowNavbarSearch = shouldShow => dispatch => dispatch(\r\n setShowNavbarSearchAction(shouldShow)\r\n)\r\n","import { apiCallBegan } from \"./api\"\r\nimport { createSlice } from \"@reduxjs/toolkit\"\r\n\r\nexport const monitorSlice = createSlice({\r\n name: \"monitor\",\r\n initialState: {\r\n cartSimulation: [],\r\n cartSimulationLoading: false,\r\n loadingCustomerOrder: false,\r\n customerOrder: []\r\n },\r\n reducers: {\r\n simulateOrderRequested: state => {\r\n state.cartSimulationLoading = true\r\n },\r\n simulateOrderRequestReceived: (state, action) => ({\r\n ...state,\r\n cartSimulation: action.payload,\r\n cartSimulationLoading: false\r\n }),\r\n simulateOrderFailed: state => {\r\n state.cartSimulationLoading = false\r\n },\r\n resetPlacedOrder: state => ({\r\n ...state,\r\n cartSimulation: []\r\n }),\r\n fetchOrderRequestStarted: state => {\r\n state.loadingCustomerOrder = true\r\n },\r\n fetchOrderRequestReceived: (state, action) => ({\r\n ...state,\r\n customerOrder: action.payload,\r\n loadingCustomerOrder: false\r\n }),\r\n fetchOrderFailed: state => {\r\n state.loadingCustomerOrder = false\r\n }\r\n }\r\n})\r\n\r\nexport default monitorSlice.reducer\r\n\r\nconst {\r\n simulateOrderRequested,\r\n simulateOrderRequestReceived,\r\n simulateOrderFailed,\r\n resetPlacedOrder,\r\n fetchOrderRequestStarted,\r\n fetchOrderRequestReceived,\r\n fetchOrderFailed\r\n} = monitorSlice.actions\r\n\r\nexport const simulateOrder = (authToken, rows) => dispatch => dispatch(\r\n apiCallBegan({\r\n url: \"/api/ProductInfo/SimulateOrder\",\r\n onStart: simulateOrderRequested.type,\r\n onSuccess: simulateOrderRequestReceived.type,\r\n onError: simulateOrderFailed.type,\r\n method: \"POST\",\r\n data: {\r\n authToken: authToken,\r\n rows: rows\r\n }\r\n })\r\n)\r\n\r\nexport const resetOrder = () => dispatch => dispatch(resetPlacedOrder())\r\n\r\nexport const fetchCustomerOrder = orderNumber => dispatch => dispatch(\r\n apiCallBegan({\r\n url: `/api/ProductInfo/GetCustomerOrder?orderNumber=${orderNumber}`,\r\n onStart: fetchOrderRequestStarted.type,\r\n onSuccess: fetchOrderRequestReceived.type,\r\n onError: fetchOrderFailed.type\r\n })\r\n)\r\n"],"sourceRoot":""}