@wayke-se/components-react 5.2.0 → 6.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +260 -140
  2. package/dist/assets/StyreneA-Bold-Web-4CXEYQLA-4CXEYQLA.woff2 +0 -0
  3. package/dist/assets/StyreneA-Bold-Web-AGBUOKS2-AGBUOKS2.woff +0 -0
  4. package/dist/assets/StyreneA-Light-Web-DAMPSUFB-DAMPSUFB.woff +0 -0
  5. package/dist/assets/StyreneA-Light-Web-EE4AJECE-EE4AJECE.woff2 +0 -0
  6. package/dist/assets/StyreneA-Medium-Web-53Q6X35A-53Q6X35A.woff +0 -0
  7. package/dist/assets/StyreneA-Medium-Web-7KYQNCKQ-7KYQNCKQ.woff2 +0 -0
  8. package/dist/assets/StyreneA-Regular-Web-7SAOGHB5-7SAOGHB5.woff2 +0 -0
  9. package/dist/assets/StyreneA-Regular-Web-XFBCXNPA-XFBCXNPA.woff +0 -0
  10. package/dist/chunks/chunk-XBJKSIMP.js +2 -0
  11. package/dist/chunks/chunk-XBJKSIMP.js.map +7 -0
  12. package/dist/chunks/dist-3TYBTGV5.js +1969 -0
  13. package/dist/chunks/dist-3TYBTGV5.js.map +7 -0
  14. package/dist/index.js +1037 -3129
  15. package/dist/index.js.map +4 -4
  16. package/dist/style.css +1 -0
  17. package/dist/types/src/@types/filter.d.ts +7 -1
  18. package/dist/types/src/Gql/ad/legacyWaykeId.d.ts +1 -0
  19. package/dist/types/src/Gql/ad/propertyTree.d.ts +5 -0
  20. package/dist/types/src/Gql/ad/queries.d.ts +9 -0
  21. package/dist/types/src/Gql/ad/types.d.ts +378 -0
  22. package/dist/types/src/Gql/ad/useAd.d.ts +8 -0
  23. package/dist/types/src/Gql/ad/useInsuranceInquiry.d.ts +11 -0
  24. package/dist/types/src/Gql/ad/useLoanCalculation.d.ts +14 -0
  25. package/dist/types/src/Gql/ad/useRelatedAds.d.ts +12 -0
  26. package/dist/types/src/Gql/ad/view.d.ts +94 -0
  27. package/dist/types/src/Gql/client.d.ts +11 -0
  28. package/dist/types/src/Gql/config.d.ts +9 -0
  29. package/dist/types/src/Gql/facets.d.ts +19 -0
  30. package/dist/types/src/Gql/hit.d.ts +5 -0
  31. package/dist/types/src/Gql/legacyParams.d.ts +7 -0
  32. package/dist/types/src/Gql/queries.d.ts +17 -0
  33. package/dist/types/src/Gql/searchParams.d.ts +55 -0
  34. package/dist/types/src/Gql/suggest.d.ts +8 -0
  35. package/dist/types/src/Gql/types.d.ts +131 -0
  36. package/dist/types/src/Gql/useAdsSearch.d.ts +21 -0
  37. package/dist/types/src/State/Ad/AdContext.d.ts +5 -0
  38. package/dist/types/src/State/Router/RouterContext.d.ts +15 -0
  39. package/dist/types/src/State/Router/RouterProvider.d.ts +6 -0
  40. package/dist/types/src/State/Router/useRouter.d.ts +2 -0
  41. package/dist/types/src/State/Search/SearchContext.d.ts +15 -9
  42. package/dist/types/src/State/Search/SearchProvider.d.ts +1 -5
  43. package/dist/types/src/State/Settings/SettingsContext.d.ts +2 -12
  44. package/dist/types/src/State/Settings/settings.d.ts +62 -0
  45. package/dist/types/src/State/Settings/useSettings.d.ts +1 -1
  46. package/dist/types/src/components/ActionList/index.d.ts +3 -10
  47. package/dist/types/src/components/DocumentList/index.d.ts +3 -3
  48. package/dist/types/src/components/Filter/index.d.ts +1 -3
  49. package/dist/types/src/components/FilterPanel/checkListFacet.d.ts +2 -3
  50. package/dist/types/src/components/FilterPanel/colorFacet.d.ts +2 -3
  51. package/dist/types/src/components/FilterPanel/faceSelector.d.ts +2 -3
  52. package/dist/types/src/components/FilterPanel/index.d.ts +8 -15
  53. package/dist/types/src/components/FilterPanel/rangeFacet.d.ts +3 -3
  54. package/dist/types/src/components/FinancialOptions/LoanModal.d.ts +3 -7
  55. package/dist/types/src/components/FinancialOptions/index.d.ts +5 -7
  56. package/dist/types/src/components/FinancialOptions/leasing.d.ts +3 -3
  57. package/dist/types/src/components/FinancialOptions/loan.d.ts +3 -7
  58. package/dist/types/src/components/Gallery/index.d.ts +3 -5
  59. package/dist/types/src/components/Grid/index.d.ts +3 -7
  60. package/dist/types/src/components/InsuranceOptions/Insurance.d.ts +4 -6
  61. package/dist/types/src/components/InsuranceOptions/InsuranceFree.d.ts +5 -7
  62. package/dist/types/src/components/InsuranceOptions/InsuranceFreeModal.d.ts +4 -4
  63. package/dist/types/src/components/InsuranceOptions/InsuranceModal.d.ts +4 -6
  64. package/dist/types/src/components/InsuranceOptions/index.d.ts +5 -6
  65. package/dist/types/src/components/LeadForm/index.d.ts +1 -6
  66. package/dist/types/src/components/Lightbox/index.d.ts +2 -2
  67. package/dist/types/src/components/Map/index.d.ts +4 -2
  68. package/dist/types/src/components/OpeningHours/index.d.ts +2 -2
  69. package/dist/types/src/components/ProductCard/HitCard.d.ts +10 -0
  70. package/dist/types/src/components/ProductCard/index.d.ts +9 -13
  71. package/dist/types/src/components/SearchBar/index.d.ts +4 -1
  72. package/dist/types/src/components/SearchBar/wrapper.d.ts +10 -0
  73. package/dist/types/src/components/SortSelect/index.d.ts +1 -2
  74. package/dist/types/src/hooks/useSubmitLead.d.ts +1 -1
  75. package/dist/types/src/index.d.ts +5 -4
  76. package/dist/types/src/layouts/WaykeComposite.d.ts +3 -8
  77. package/dist/types/src/layouts/WaykeCompositeWithProvider.d.ts +1 -1
  78. package/dist/types/src/layouts/search/index.d.ts +6 -7
  79. package/dist/types/src/layouts/searchItem/Accessories/AccessoryModal.d.ts +2 -2
  80. package/dist/types/src/layouts/searchItem/Accessories/index.d.ts +2 -2
  81. package/dist/types/src/layouts/searchItem/Branch.d.ts +3 -4
  82. package/dist/types/src/layouts/searchItem/CheckList.d.ts +3 -15
  83. package/dist/types/src/layouts/searchItem/Documents.d.ts +2 -2
  84. package/dist/types/src/layouts/searchItem/ManufacturerPackagesOption.d.ts +2 -2
  85. package/dist/types/src/layouts/searchItem/PackageOptions.d.ts +3 -3
  86. package/dist/types/src/layouts/searchItem/Property.d.ts +1 -6
  87. package/dist/types/src/layouts/searchItem/Related.d.ts +5 -6
  88. package/dist/types/src/layouts/searchItem/index.d.ts +8 -6
  89. package/dist/types/src/layouts/searchItem/useEcom.d.ts +7 -3
  90. package/dist/types/src/providers/WaykeProvider.d.ts +7 -21
  91. package/dist/types/src/utils/image.d.ts +14 -0
  92. package/dist/types/src/utils/sortOptions.d.ts +4 -13
  93. package/package.json +26 -22
  94. package/dist/assets/default.css +0 -1
  95. package/dist/assets/fonts/slick.svg +0 -14
  96. package/dist/index.mjs +0 -5511
  97. package/dist/index.mjs.map +0 -7
  98. package/dist/types/src/@types/action.d.ts +0 -3
  99. package/dist/types/src/@types/codegen/types.d.ts +0 -433
  100. package/dist/types/src/@types/queryFilter.d.ts +0 -5
  101. package/dist/types/src/@types/search.d.ts +0 -114
  102. package/dist/types/src/State/CentralStorage/CentralStorageContext.d.ts +0 -5
  103. package/dist/types/src/State/CentralStorage/CentralStorageProvider.d.ts +0 -6
  104. package/dist/types/src/State/CentralStorage/useCentralStorage.d.ts +0 -6
  105. package/dist/types/src/State/Path/PathContext.d.ts +0 -8
  106. package/dist/types/src/State/Path/PathProvider.d.ts +0 -6
  107. package/dist/types/src/State/Path/reducer.d.ts +0 -14
  108. package/dist/types/src/State/Path/usePath.d.ts +0 -3
  109. package/dist/types/src/State/RelatedSearch/RelatedSearchContext.d.ts +0 -9
  110. package/dist/types/src/State/RelatedSearch/RelatedSearchProvider.d.ts +0 -9
  111. package/dist/types/src/State/RelatedSearch/useRelatedSearch.d.ts +0 -2
  112. package/dist/types/src/State/Settings/SettingsProvider.d.ts +0 -11
  113. package/dist/types/src/components/Video/QuickNavVideo.d.ts +0 -7
  114. package/dist/types/src/hooks/apolloTypes.d.ts +0 -6
  115. package/dist/types/src/hooks/useHasBeenVisible.d.ts +0 -2
  116. package/dist/types/src/hooks/useHashGuid.d.ts +0 -2
  117. package/dist/types/src/hooks/useInsurance.d.ts +0 -4
  118. package/dist/types/src/hooks/useLoan.d.ts +0 -4
  119. package/dist/types/src/hooks/useOnScreen.d.ts +0 -2
  120. package/dist/types/src/hooks/usePrevious.d.ts +0 -2
  121. package/dist/types/src/hooks/useSearchItem.d.ts +0 -4
  122. package/dist/types/src/hooks/useSearchItemBranch.d.ts +0 -4
  123. package/dist/types/src/hooks/useSessionStorage.d.ts +0 -7
  124. package/dist/types/src/layouts/searchItem/BranchModal.d.ts +0 -9
  125. package/dist/types/src/providers/WaykeItemProvidet.d.ts +0 -24
  126. package/dist/types/src/providers/graphqlProvider.d.ts +0 -6
  127. package/dist/types/src/queries/INSURANCE_CALCULATION.d.ts +0 -2
  128. package/dist/types/src/queries/LOAN_CALCULATION.d.ts +0 -2
  129. package/dist/types/src/queries/SEARCH_ITEM_BRANCH_QUERY.d.ts +0 -2
  130. package/dist/types/src/queries/SEARCH_ITEM_QUERY.d.ts +0 -2
  131. package/dist/types/src/utils/deep-copy.d.ts +0 -5
  132. package/dist/types/src/utils/regex.d.ts +0 -3
  133. package/dist/types/src/utils/specification.d.ts +0 -28
  134. package/dist/types/src/utils/url.d.ts +0 -1
  135. package/dist/types/src/utils/vehicle-properties/compare-basic-properties.d.ts +0 -3
  136. package/dist/types/src/utils/vehicle-properties/compare-categories.d.ts +0 -3
  137. package/dist/types/src/utils/vehicle-properties/compare-properties.d.ts +0 -3
  138. package/dist/types/src/utils/vehicle-properties/custom-property-adder.d.ts +0 -13
  139. package/dist/types/src/utils/vehicle-properties/property-remover.d.ts +0 -7
  140. package/dist/types/src/utils/vehicle-properties/property-tree-creator.d.ts +0 -31
  141. package/dist/types/src/utils/vehicle-properties/property-tree-sorter.d.ts +0 -3
  142. /package/dist/assets/{ajax-loader.gif → ajax-loader-BOAPMZMT.gif} +0 -0
  143. /package/dist/assets/{fonts/slick.eot → slick-EVLS6IWX.eot} +0 -0
  144. /package/dist/assets/{fonts/slick.woff → slick-MU5EZO5G.woff} +0 -0
  145. /package/dist/assets/{fonts/slick.ttf → slick-NKQ64RRA.ttf} +0 -0
@@ -0,0 +1,94 @@
1
+ import { Ad, AdAccessory, AdMediaItem, PaymentRange } from './types';
2
+ /** A number from the API, which sends some amounts as strings. */
3
+ export declare const num: (value: string | number | null | undefined) => number | undefined;
4
+ export declare const str: (value: string | null | undefined) => string | undefined;
5
+ /** What every ad page event carries. */
6
+ export declare const adEvent: (ad: Ad) => {
7
+ id: string;
8
+ branchId: string;
9
+ branchName: string | undefined;
10
+ };
11
+ /** Ecom and ev-calculation are keyed on the legacy waykeId, not on ad.id. */
12
+ export declare const waykeId: (ad: Ad) => string;
13
+ export declare const platformChannel: (ad: Ad) => {
14
+ __typename: string;
15
+ status?: string;
16
+ inventoryStatus?: string;
17
+ publishedAt?: string | null;
18
+ soldAt?: string | null;
19
+ deliveryTime?: {
20
+ __typename: string;
21
+ date?: string;
22
+ from?: string;
23
+ to?: string;
24
+ unit?: string;
25
+ } | null;
26
+ } | undefined;
27
+ export declare const price: (ad: Ad) => number;
28
+ /** How much the price was lowered, when it was. */
29
+ export declare const discount: (ad: Ad) => number | undefined;
30
+ /** The delivery date of a car that is not in stock yet. */
31
+ export declare const availableFrom: (ad: Ad) => Date | undefined;
32
+ export declare const publishedAt: (ad: Ad) => Date | undefined;
33
+ /** Buy online is offered when the branch has it, unless it is switched off for Wayke. */
34
+ export declare const ecom: (ad: Ad) => {
35
+ enabled: boolean;
36
+ reserved: boolean;
37
+ };
38
+ export interface ContactPerson {
39
+ name?: string;
40
+ email?: string;
41
+ phone?: string;
42
+ avatar?: string;
43
+ }
44
+ /** The person to contact about the ad: the assigned salesperson, else the branch's default. */
45
+ export declare const contactPerson: (ad: Ad) => ContactPerson | undefined;
46
+ export type DayKey = 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
47
+ export type WeekOpeningHours = Partial<Record<DayKey, {
48
+ from: string;
49
+ until: string;
50
+ } | null>>;
51
+ export declare const openingHours: (branch: Ad['branch']) => WeekOpeningHours | undefined;
52
+ export declare const position: (branch: Ad['branch']) => {
53
+ latitude: number;
54
+ longitude: number;
55
+ } | undefined;
56
+ export type MediaType = 'image' | 'sphere' | 'threesixty' | 'embedded';
57
+ /** One slide of the gallery: an image, a panorama, a 360 spin of several images, or a video. */
58
+ export interface GalleryMedia {
59
+ type: MediaType;
60
+ urls: string[];
61
+ }
62
+ export declare const galleryMedia: (items: AdMediaItem[]) => GalleryMedia[];
63
+ export interface Range {
64
+ current: number;
65
+ min: number;
66
+ max: number;
67
+ step: number;
68
+ }
69
+ export declare const range: (r: PaymentRange | null | undefined) => Range | undefined;
70
+ export interface LeasingOffer {
71
+ business: boolean;
72
+ monthlyCost: number;
73
+ months?: number;
74
+ mileagePerYear?: number;
75
+ name?: string;
76
+ description?: string;
77
+ image?: string;
78
+ }
79
+ /** Private and business leasing, with the dealer's promo text when there is one. */
80
+ export declare const leasingOffers: (ad: Ad) => LeasingOffer[];
81
+ export interface PackageOffer {
82
+ title: string;
83
+ description?: string;
84
+ image?: string;
85
+ link?: {
86
+ url: string;
87
+ title?: string;
88
+ };
89
+ }
90
+ export declare const packageOffers: (ad: Ad) => PackageOffer[];
91
+ /** The manufacturer's warranty package of a certified pre-owned car. */
92
+ export declare const manufacturerPackage: (ad: Ad) => PackageOffer | undefined;
93
+ /** An accessory's images, in their order. */
94
+ export declare const accessoryImages: (accessory: AdAccessory) => string[];
@@ -0,0 +1,11 @@
1
+ export interface PublicApiConfig {
2
+ url: string;
3
+ apiKey?: string;
4
+ }
5
+ export type GqlErrorKind = 'unauthorized' | 'rate-limited' | 'graphql' | 'network';
6
+ export declare class GqlError extends Error {
7
+ readonly kind: GqlErrorKind;
8
+ readonly retryAfter?: number;
9
+ constructor(kind: GqlErrorKind, message: string, retryAfter?: number);
10
+ }
11
+ export declare const gqlQuery: <T>(config: PublicApiConfig, query: string, variables: Record<string, unknown>) => Promise<T>;
@@ -0,0 +1,9 @@
1
+ import { MarketCode } from '../@types/market';
2
+ import { PublicApiConfig } from './client';
3
+ /** What every request to the public API needs, resolved once by the provider. */
4
+ export interface PublicApiSettings {
5
+ api: PublicApiConfig;
6
+ /** Narrows the search to a group of branches; without it the key's own scope applies */
7
+ branchGroupId?: string;
8
+ market: MarketCode;
9
+ }
@@ -0,0 +1,19 @@
1
+ import { MarketCode } from '../@types/market';
2
+ import { RangeFilter } from './searchParams';
3
+ import { AdsResult, Facet } from './types';
4
+ export interface FacetOption {
5
+ value: string;
6
+ count: number;
7
+ selected: boolean;
8
+ }
9
+ /**
10
+ * The values of a list filter, with counts from the filtered result (where a
11
+ * selected filter's own facet is counted without it, see useAdsSearch). A
12
+ * selected value is always listed, so it can be unticked.
13
+ */
14
+ export declare const listOptions: (field: string, params: URLSearchParams, facets: Facet[] | undefined) => FacetOption[];
15
+ export declare const isRangeFilter: (key: string) => key is RangeFilter;
16
+ /** The bucket start values of a slider, ascending, from the unfiltered search. */
17
+ export declare const rangeValues: (key: RangeFilter, unfiltered: AdsResult | undefined, market: MarketCode) => number[];
18
+ /** How many values of a filter are picked: list values, or 1 for a set range. */
19
+ export declare const selectedCount: (key: string, params: URLSearchParams) => number;
@@ -0,0 +1,5 @@
1
+ import { Money, SearchHit } from './types';
2
+ /** An amount from the API, or undefined when it is missing or not above zero. */
3
+ export declare const toAmount: (money?: Money | null) => number | undefined;
4
+ /** The first image of a hit, if any. */
5
+ export declare const hitImage: (hit: SearchHit) => string | undefined;
@@ -0,0 +1,7 @@
1
+ /** True when the params carry anything that is not already in the new grammar. */
2
+ export declare const hasLegacyParams: (params: URLSearchParams) => boolean;
3
+ /**
4
+ * Legacy params → canonical new-grammar params. Idempotent: params already in
5
+ * the new grammar come back unchanged (apart from canonical ordering).
6
+ */
7
+ export declare const migrateLegacyParams: (input: URLSearchParams) => URLSearchParams;
@@ -0,0 +1,17 @@
1
+ export declare const SEARCH_HIT_FIELDS = "\n ad {\n id\n salesDescription { title }\n pricing {\n cash { price { amount } oldPrice { amount } deductibleVat }\n leasing { leasingMonthlyPayment { amount } }\n companyLeasing { leasingMonthlyPayment { amount } }\n }\n media(limit: 1) { items { ... on AdImage { id url formats { format url } } } }\n branch { id displayName }\n channels { ... on PlatformChannel { status soldAt } }\n }\n iteration {\n logistics { odometerReading { value unit } }\n item {\n ... on Vehicle {\n displayName\n manufacturer { stringValue }\n modelSeries { stringValue }\n modelYear { intValue }\n registrationNumber { stringValue }\n driveline { fuelTypesString { stringValue } }\n attributes { transmission { formattedValue } }\n }\n }\n }\n";
2
+ export declare const ADS_ARGUMENTS = "\n market: $market\n q: $q\n branchGroupId: $branchGroupId\n page: $page\n perPage: $perPage\n sort: $sort\n soldWithinDays: 0\n manufacturer: $manufacturer\n model: $model\n modelSeries: $modelSeries\n fuelType: $fuelType\n gearboxType: $gearboxType\n branchDisplayName: $branchDisplayName\n colorName: $colorName\n environmentClass: $environmentClass\n segment: $segment\n drivetrainType: $drivetrainType\n bodyStyle: $bodyStyle\n engineBaseType: $engineBaseType\n trimLevel: $trimLevel\n inventoryStatus: $inventoryStatus\n branchCity: $branchCity\n certifiedPreOwned: $certifiedPreOwned\n isDemoVersion: $isDemoVersion\n deductibleVat: $deductibleVat\n ecom: $ecom\n leasing: $leasing\n businessLeasing: $businessLeasing\n cashPriceMin: $cashPriceMin\n cashPriceMax: $cashPriceMax\n odometerReadingMin: $odometerReadingMin\n odometerReadingMax: $odometerReadingMax\n modelYearMin: $modelYearMin\n modelYearMax: $modelYearMax\n leasingPriceMin: $leasingPriceMin\n leasingPriceMax: $leasingPriceMax\n companyLeasingPriceMin: $companyLeasingPriceMin\n companyLeasingPriceMax: $companyLeasingPriceMax\n";
3
+ export declare const ADS_VARIABLE_DEFINITIONS = "\n $market: [String]\n $q: String\n $branchGroupId: String\n $page: Int\n $perPage: Int\n $sort: AdsSort\n $manufacturer: [String]\n $model: [String]\n $modelSeries: [String]\n $fuelType: [String]\n $gearboxType: [String]\n $branchDisplayName: [String]\n $colorName: [String]\n $environmentClass: [String]\n $segment: [String]\n $drivetrainType: [String]\n $bodyStyle: [String]\n $engineBaseType: [String]\n $trimLevel: [String]\n $inventoryStatus: [String]\n $branchCity: [String]\n $certifiedPreOwned: Boolean\n $isDemoVersion: Boolean\n $deductibleVat: Boolean\n $ecom: Boolean\n $leasing: Boolean\n $businessLeasing: Boolean\n $cashPriceMin: Float\n $cashPriceMax: Float\n $odometerReadingMin: Int\n $odometerReadingMax: Int\n $modelYearMin: Int\n $modelYearMax: Int\n $leasingPriceMin: Float\n $leasingPriceMax: Float\n $companyLeasingPriceMin: Float\n $companyLeasingPriceMax: Float\n";
4
+ /** Alias of the facet-only search for one selected list filter, see buildSearchQuery. */
5
+ export declare const multiSelectFacetAlias: (field: string) => string;
6
+ /**
7
+ * One request for the search page: the filtered list with its facets and, for
8
+ * every list filter that has a selection, that facet counted WITHOUT its own
9
+ * filter. The legacy search counted facets that way ("multi-select"), so the
10
+ * other makes stay listed with their counts after picking one; the public API
11
+ * counts facets on the filtered result, where only the picked make remains.
12
+ */
13
+ export declare const buildSearchQuery: (selectedListFilters: string[]) => string;
14
+ export declare const SEARCH_QUERY: string;
15
+ /** Unfiltered facets and histograms: the filter panel's full value lists and slider domains. */
16
+ export declare const FACETS_QUERY = "\nquery SearchFacets($market: [String], $branchGroupId: String) {\n search {\n ads(market: $market, branchGroupId: $branchGroupId, perPage: 0, soldWithinDays: 0) {\n found\n facets { field counts { value count } }\n histograms {\n price { value count }\n odometerReading { value count }\n leasingPrice { value count }\n businessLeasingPrice { value count }\n }\n }\n }\n}\n";
17
+ export declare const SUGGEST_QUERY = "\nquery Suggest($market: [String], $branchGroupId: String, $q: String!, $limit: Int) {\n search {\n ads(market: $market, branchGroupId: $branchGroupId, q: $q, perPage: 0, soldWithinDays: 0) {\n suggest(limit: $limit) { label count dimension filters { field value } }\n }\n }\n}\n";
@@ -0,0 +1,55 @@
1
+ import { MarketCode } from '../@types/market';
2
+ export declare const FREE_TEXT = "q";
3
+ export declare const SORT = "sort";
4
+ export declare const PAGE = "page";
5
+ /** Facet filters whose URL key, facet field and search argument share a name. */
6
+ export declare const LIST_FILTERS: readonly ['manufacturer', 'model', 'modelSeries', 'fuelType', 'gearboxType', 'branchDisplayName', 'colorName', 'environmentClass', 'segment', 'drivetrainType', 'bodyStyle', 'engineBaseType', 'trimLevel', 'inventoryStatus', 'branchCity'];
7
+ export type ListFilter = (typeof LIST_FILTERS)[number];
8
+ /** Range filters: URL base key → the `…Min`/`…Max` argument pair. */
9
+ export declare const RANGE_FILTERS: {
10
+ readonly price: 'cashPrice';
11
+ readonly odometer: 'odometerReading';
12
+ readonly modelYear: 'modelYear';
13
+ readonly privateLease: 'leasingPrice';
14
+ readonly businessLease: 'companyLeasingPrice';
15
+ };
16
+ export type RangeFilter = keyof typeof RANGE_FILTERS;
17
+ export declare const BOOLEAN_FILTERS: readonly ['certifiedPreOwned', 'isDemoVersion', 'deductibleVat', 'ecom', 'leasing', 'businessLeasing'];
18
+ export interface SortDefinition {
19
+ field: string;
20
+ direction: 'asc' | 'desc';
21
+ /** Legacy token the sort panel translates; see Utils/SortOptions.ts. */
22
+ legacyName: string;
23
+ }
24
+ /** `sort=` keys, in the order the sort panel lists them. The first is the default. */
25
+ export declare const SORT_OPTIONS: Record<string, SortDefinition>;
26
+ export declare const DEFAULT_SORT = "published-desc";
27
+ /** Page size as components-react's legacy search had it: 30, also after a filter. */
28
+ export declare const pageSize: (_params: URLSearchParams) => number;
29
+ export declare const isKnownKey: (key: string) => boolean;
30
+ /** Odometer values in the URL are in the market's display unit; the API takes km. */
31
+ export declare const kmPerOdometerUnit: (market: MarketCode) => 1 | 10;
32
+ export interface AdsVariables {
33
+ market: string[];
34
+ q?: string;
35
+ page: number;
36
+ perPage: number;
37
+ sort?: {
38
+ field: string;
39
+ direction: 'asc' | 'desc';
40
+ };
41
+ [key: string]: unknown;
42
+ }
43
+ /**
44
+ * URL params → `search.ads` variables. Unknown keys are ignored; the page is read
45
+ * from `page` unless given explicitly (load more passes it).
46
+ */
47
+ export declare const toSearchVariables: (params: URLSearchParams, market: MarketCode, options?: {
48
+ page?: number;
49
+ perPage?: number;
50
+ }) => AdsVariables;
51
+ /** The canonical form written to the address bar: known keys only, sorted, no paging. */
52
+ export declare const canonicalParams: (params: URLSearchParams) => URLSearchParams;
53
+ export declare const toggleListValue: (params: URLSearchParams, key: string, value: string) => URLSearchParams;
54
+ export declare const withSort: (params: URLSearchParams, sortKey: string) => URLSearchParams;
55
+ export declare const withPage: (params: URLSearchParams, page: number) => URLSearchParams;
@@ -0,0 +1,8 @@
1
+ import { PublicApiSettings } from './config';
2
+ import { Suggestion } from './types';
3
+ export declare const fetchSuggestions: (settings: PublicApiSettings, q: string, limit?: number) => Promise<Suggestion[]>;
4
+ /**
5
+ * The suggestion's filters as URL params. Built with URLSearchParams so values
6
+ * with `+` or `&` (Bensin+El) survive the round trip.
7
+ */
8
+ export declare const suggestionParams: (suggestion: Suggestion) => URLSearchParams;
@@ -0,0 +1,131 @@
1
+ export interface Money {
2
+ amount: string;
3
+ }
4
+ export interface AdImageFormat {
5
+ format: string;
6
+ url: string;
7
+ }
8
+ export interface SearchHit {
9
+ ad: {
10
+ id: string;
11
+ salesDescription: {
12
+ title: string;
13
+ } | null;
14
+ pricing: {
15
+ cash: {
16
+ price: Money;
17
+ oldPrice: Money | null;
18
+ deductibleVat: boolean;
19
+ } | null;
20
+ leasing: {
21
+ leasingMonthlyPayment: Money | null;
22
+ } | null;
23
+ companyLeasing: {
24
+ leasingMonthlyPayment: Money | null;
25
+ } | null;
26
+ } | null;
27
+ media: {
28
+ items: ({
29
+ id?: string;
30
+ url?: string;
31
+ formats?: AdImageFormat[];
32
+ } | null)[];
33
+ };
34
+ branch: {
35
+ id: string;
36
+ displayName: string | null;
37
+ };
38
+ channels: ({
39
+ status?: string;
40
+ soldAt?: string | null;
41
+ } | null)[];
42
+ };
43
+ iteration: {
44
+ logistics: {
45
+ odometerReading: {
46
+ value: number;
47
+ unit: 'KILOMETER' | 'SCANDINAVIAN_MILE';
48
+ } | null;
49
+ } | null;
50
+ item: {
51
+ displayName?: string;
52
+ manufacturer?: {
53
+ stringValue: string;
54
+ } | null;
55
+ modelSeries?: {
56
+ stringValue: string;
57
+ } | null;
58
+ modelYear?: {
59
+ intValue: number;
60
+ } | null;
61
+ registrationNumber?: {
62
+ stringValue: string;
63
+ } | null;
64
+ driveline?: {
65
+ fuelTypesString: {
66
+ stringValue: string;
67
+ } | null;
68
+ } | null;
69
+ attributes?: {
70
+ transmission: {
71
+ formattedValue: string;
72
+ } | null;
73
+ } | null;
74
+ } | null;
75
+ } | null;
76
+ }
77
+ export interface FacetCount {
78
+ value: string;
79
+ count: number;
80
+ }
81
+ export interface Facet {
82
+ field: string;
83
+ counts: FacetCount[];
84
+ }
85
+ export interface HistogramBucket {
86
+ value: number;
87
+ count: number;
88
+ }
89
+ export interface AdsResult {
90
+ found: number;
91
+ page: number;
92
+ perPage: number;
93
+ hits: SearchHit[];
94
+ facets?: Facet[] | null;
95
+ histograms?: {
96
+ price: HistogramBucket[];
97
+ odometerReading: HistogramBucket[];
98
+ leasingPrice: HistogramBucket[];
99
+ businessLeasingPrice: HistogramBucket[];
100
+ } | null;
101
+ }
102
+ export interface Suggestion {
103
+ label: string;
104
+ count: number;
105
+ dimension: string;
106
+ filters: {
107
+ field: string;
108
+ value: string;
109
+ }[];
110
+ }
111
+ export interface SearchData {
112
+ search: {
113
+ ads: AdsResult | null;
114
+ /** facets_<field>: that facet counted without its own filter */
115
+ [alias: string]: {
116
+ facets?: Facet[] | null;
117
+ } | AdsResult | null | undefined;
118
+ } | null;
119
+ }
120
+ export interface FacetsData {
121
+ search: {
122
+ ads: AdsResult | null;
123
+ } | null;
124
+ }
125
+ export interface SuggestData {
126
+ search: {
127
+ ads: {
128
+ suggest: Suggestion[];
129
+ } | null;
130
+ } | null;
131
+ }
@@ -0,0 +1,21 @@
1
+ import { PublicApiSettings } from './config';
2
+ import { AdsResult, Facet, SearchHit } from './types';
3
+ export interface AdsSearchResult {
4
+ found: number;
5
+ page: number;
6
+ perPage: number;
7
+ /** Every page loaded so far */
8
+ hits: SearchHit[];
9
+ /** List facets of the filtered result, each selected one counted without its own filter */
10
+ facets: Facet[];
11
+ }
12
+ declare const useAdsSearch: (params: URLSearchParams | undefined, settings: PublicApiSettings) => {
13
+ unfiltered: AdsResult | undefined;
14
+ result: AdsSearchResult | undefined;
15
+ loading: boolean;
16
+ loadingMore: boolean;
17
+ error: boolean;
18
+ hasMore: boolean;
19
+ loadMore: () => Promise<void>;
20
+ };
21
+ export default useAdsSearch;
@@ -0,0 +1,5 @@
1
+ import { Ad } from '../../Gql/ad/types';
2
+ /** The ad the page shows, for the parts of the page that need more than their props. */
3
+ export declare const AdContext: import("react").Context<Ad | undefined>;
4
+ declare const useAdContext: () => Ad;
5
+ export default useAdContext;
@@ -0,0 +1,15 @@
1
+ export interface RouterContextProps {
2
+ /** The vehicle that is open, from the hash or the path */
3
+ id?: string;
4
+ /** The query string in the address bar, without `?` */
5
+ search: string;
6
+ /** Link to a vehicle; undefined when routing is `none` */
7
+ itemHref: (id: string) => string | undefined;
8
+ /** Link back to the search from a vehicle; undefined when there is none */
9
+ searchHref?: string;
10
+ /** Click handler for the links above: same-site path links open without a reload */
11
+ onLinkClick: (e: React.MouseEvent<HTMLAnchorElement>, href: string) => void;
12
+ /** Writes the search filters to the address bar when routing.syncUrl is on */
13
+ writeSearch: (params: URLSearchParams, replace?: boolean) => void;
14
+ }
15
+ export declare const RouterContext: import("react").Context<RouterContextProps>;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ interface RouterProviderProps {
3
+ children: React.ReactNode;
4
+ }
5
+ declare const RouterProvider: ({ children }: RouterProviderProps) => React.JSX.Element;
6
+ export default RouterProvider;
@@ -0,0 +1,2 @@
1
+ declare const useRouter: () => import("./RouterContext").RouterContextProps;
2
+ export default useRouter;
@@ -1,14 +1,20 @@
1
- import { QueryFilter } from '../../@types/queryFilter';
2
- import { Document, Facet, Search } from '../../@types/search';
1
+ import { AdsResult } from '../../Gql/types';
2
+ import { AdsSearchResult } from '../../Gql/useAdsSearch';
3
3
  export interface SearchContextProps {
4
+ /** The filters in the searchParams.ts grammar; empty until the search has initialized */
5
+ params: URLSearchParams;
6
+ /** The filtered result, every page loaded so far */
7
+ result?: AdsSearchResult;
8
+ /** Facets and histograms without filters: the panel's full value lists and slider domains */
9
+ unfiltered?: AdsResult;
4
10
  loading: boolean;
5
- response?: Search;
11
+ loadingMore: boolean;
6
12
  error: boolean;
7
- documents?: Document[];
8
- initialFacets?: Facet[];
9
- queryFilter: QueryFilter;
10
- onFilterUpdate: (nextQuery: string) => void;
11
- onLoadMore: () => void;
12
- onInitialize: (initialQueryParams?: URLSearchParams) => void;
13
+ hasMore: boolean;
14
+ /** Applies new filters. Old keys and sort tokens are translated. */
15
+ update: (next: URLSearchParams | string) => void;
16
+ loadMore: () => void;
17
+ /** Starts the search with the url's filters and/or initialQueryParams */
18
+ initialize: (initialQueryParams?: URLSearchParams) => void;
13
19
  }
14
20
  export declare const SearchContext: import("react").Context<SearchContextProps>;
@@ -1,10 +1,6 @@
1
1
  import React from 'react';
2
2
  interface SearchProviderProps {
3
- url: string;
4
- apiKey?: string;
5
- useQueryParamsFromUrl?: boolean;
6
- pathRoute?: string;
7
3
  children: React.ReactNode;
8
4
  }
9
- declare const SearchProvider: ({ url, apiKey, useQueryParamsFromUrl, pathRoute, children, }: SearchProviderProps) => React.JSX.Element;
5
+ declare const SearchProvider: ({ children }: SearchProviderProps) => React.JSX.Element;
10
6
  export default SearchProvider;
@@ -1,12 +1,2 @@
1
- export interface SettingsContextProps {
2
- /** Base URL of the Wayke API (same host as the search url). Used for lead submission. */
3
- apiUrl?: string;
4
- googleMapsApiKey?: string;
5
- googleMapsMarker?: string;
6
- ecomSettings?: {
7
- url: string;
8
- serviceLogotypeUrl?: string;
9
- bankIdThumbprint?: string;
10
- };
11
- }
12
- export declare const SettingsContext: import("react").Context<SettingsContextProps>;
1
+ import { Settings } from './settings';
2
+ export declare const SettingsContext: import("react").Context<Settings>;
@@ -0,0 +1,62 @@
1
+ import { MarketCode } from '../../@types/market';
2
+ import { PublicApiSettings } from '../../Gql/config';
3
+ export type Environment = 'production' | 'test';
4
+ export type RoutingMode = 'hash' | 'path' | 'none';
5
+ export interface RoutingSettings {
6
+ /**
7
+ * How a vehicle is opened from the search. `hash` (default) adds `#<id>` to
8
+ * the url, `path` links to `<basePath>/<id>`, `none` makes the vehicles plain
9
+ * cards and only publishes `ItemClicked`.
10
+ */
11
+ mode?: RoutingMode;
12
+ /** Required for `path`. Relative to the current page, or an absolute url to another site. */
13
+ basePath?: string;
14
+ /** Reads and writes the search filters in the url. */
15
+ syncUrl?: boolean;
16
+ }
17
+ export interface EcomSettings {
18
+ /**
19
+ * Buy online is shown on the vehicles the dealer sells online. `false` hides it
20
+ * on this site. Default `true`.
21
+ */
22
+ enabled?: boolean;
23
+ /** Defaults to the ecom API of `environment`. */
24
+ url?: string;
25
+ /** Url to the logo shown in buy online, as an image file (not a `data:` url). */
26
+ serviceLogotypeUrl?: string;
27
+ bankIdThumbprint?: string;
28
+ }
29
+ export interface WaykeProviderSettings {
30
+ /** Which Wayke environment to use. Default `production`. */
31
+ environment?: Environment;
32
+ /** Identifies the site instead of its domain. Sent as `x-api-key`. */
33
+ apiKey?: string;
34
+ /** Limits the vehicles to a group of branches. By default the key decides which vehicles are shown. */
35
+ branchGroupId?: string;
36
+ /** Language and market. Default `SE`. */
37
+ marketCode?: MarketCode;
38
+ routing?: RoutingSettings;
39
+ /** Buy online, see EcomSettings. */
40
+ ecom?: EcomSettings;
41
+ /** A Google Maps Static API key. Without it, the map button opens Google Maps. */
42
+ googleMapsApiKey?: string;
43
+ /** Url to a custom marker for the map. */
44
+ googleMapsMarker?: string;
45
+ /** Overrides the public API url of `environment`. */
46
+ publicApiUrl?: string;
47
+ /** Overrides the lead url of `environment`. */
48
+ leadUrl?: string;
49
+ }
50
+ export interface Settings {
51
+ publicApi: PublicApiSettings;
52
+ marketCode: MarketCode;
53
+ leadUrl: string;
54
+ routing: Required<Omit<RoutingSettings, 'basePath'>> & {
55
+ basePath?: string;
56
+ };
57
+ /** Undefined when buy online is turned off. */
58
+ ecom?: Required<Pick<EcomSettings, 'url'>> & Omit<EcomSettings, 'enabled'>;
59
+ googleMapsApiKey?: string;
60
+ googleMapsMarker?: string;
61
+ }
62
+ export declare const resolveSettings: (settings?: WaykeProviderSettings) => Settings;
@@ -1,2 +1,2 @@
1
- declare const useSettings: () => import("./SettingsContext").SettingsContextProps;
1
+ declare const useSettings: () => import("./settings").Settings;
2
2
  export default useSettings;
@@ -1,17 +1,10 @@
1
1
  import React from 'react';
2
- import { Branch, ContactOptions, Ecommerce, Maybe, VehicleData } from '../../@types/codegen/types';
3
2
  import { ConversionOption } from '../../@types/conversion';
4
- import { MarketCode } from '../../@types/market';
5
3
  interface ActionListProps {
6
- id: string;
7
- title?: string | null;
8
- vehicleData?: Maybe<VehicleData>;
9
- branch?: Maybe<Branch>;
10
- contact?: Maybe<ContactOptions>;
11
- ecommerce?: Maybe<Ecommerce>;
12
- marketCode?: MarketCode;
4
+ title: string;
13
5
  conversionOptions?: ConversionOption[];
6
+ /** Undefined when the site turns buy online off, which hides the buy button. */
14
7
  toggleEcomModal?: () => void;
15
8
  }
16
- declare const ActionList: ({ id, title, vehicleData, contact, branch, ecommerce, marketCode, conversionOptions, toggleEcomModal, }: ActionListProps) => React.JSX.Element;
9
+ declare const ActionList: ({ title, conversionOptions, toggleEcomModal, }: ActionListProps) => React.JSX.Element;
17
10
  export default ActionList;
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import { Scalars } from '../../@types/codegen/types';
2
+ import { AdDocument } from '../../Gql/ad/types';
3
3
  interface PdfDownloadItemProps {
4
- document: Scalars['FileDocument']['input'];
4
+ document: AdDocument;
5
5
  }
6
6
  export declare const PdfDownloadItem: ({ document }: PdfDownloadItemProps) => React.JSX.Element;
7
7
  interface IDocumentList {
8
- documents: Scalars['FileDocument']['input'][];
8
+ documents: AdDocument[];
9
9
  }
10
10
  export declare const DocumentList: ({ documents }: IDocumentList) => React.JSX.Element;
11
11
  export default DocumentList;
@@ -1,9 +1,7 @@
1
1
  import React from 'react';
2
2
  import { SearchFilterTypes } from '../../@types/filter';
3
- import { MarketCode } from '../../@types/market';
4
3
  interface FilterProps {
5
- marketCode?: MarketCode;
6
4
  filterList?: SearchFilterTypes[];
7
5
  }
8
- declare const Filter: ({ marketCode, filterList }: FilterProps) => React.JSX.Element | null;
6
+ declare const Filter: ({ filterList }: FilterProps) => React.JSX.Element | null;
9
7
  export default Filter;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
- import { Facet } from '../../@types/search';
3
2
  interface ChecklistFacetProps {
4
- facet: Facet;
3
+ id: string;
5
4
  }
6
- declare const ChecklistFacet: ({ facet }: ChecklistFacetProps) => React.JSX.Element;
5
+ declare const ChecklistFacet: ({ id }: ChecklistFacetProps) => React.JSX.Element;
7
6
  export default ChecklistFacet;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
- import { Facet } from '../../@types/search';
3
2
  interface ColorSelectFacetProps {
4
- facet: Facet;
3
+ id: string;
5
4
  }
6
- declare const ColorSelectFacet: ({ facet }: ColorSelectFacetProps) => React.JSX.Element;
5
+ declare const ColorSelectFacet: ({ id }: ColorSelectFacetProps) => React.JSX.Element;
7
6
  export default ColorSelectFacet;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
- import { Facet } from '../../@types/search';
3
2
  interface FacetSelectorProps {
4
- facet: Facet;
3
+ id: string;
5
4
  }
6
- declare const FacetSelector: ({ facet }: FacetSelectorProps) => React.JSX.Element | null;
5
+ declare const FacetSelector: ({ id }: FacetSelectorProps) => React.JSX.Element | null;
7
6
  export default FacetSelector;