@times-components/ts-components 1.146.2-0831d531868ee6854720b5b42c0a1ccdbe6a4a70.45 → 1.146.2-be27d508c972211ad80599875cd69c63bf67d4b1.45
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.
- package/dist/components/trip-cards/TripCard.js +6 -19
- package/dist/components/trip-cards/TripCardsLayout.js +7 -14
- package/dist/components/trip-cards/__tests__/TripCardsLayout.test.js +2 -39
- package/dist/components/trip-cards/helpers.d.ts +0 -1
- package/dist/components/trip-cards/helpers.js +1 -21
- package/dist/components/trip-cards/index.js +4 -4
- package/dist/components/trip-cards/types.d.ts +0 -3
- package/package.json +3 -3
- package/rnw.js +1 -1
- package/src/components/trip-cards/TripCard.tsx +2 -49
- package/src/components/trip-cards/TripCardsLayout.tsx +6 -30
- package/src/components/trip-cards/__tests__/TripCardsLayout.test.tsx +1 -87
- package/src/components/trip-cards/helpers.ts +0 -31
- package/src/components/trip-cards/index.tsx +1 -4
- package/src/components/trip-cards/types.ts +0 -3
|
@@ -26,61 +26,17 @@ import {
|
|
|
26
26
|
StyledLink
|
|
27
27
|
} from './styles';
|
|
28
28
|
import { MoonIcon, LocationIcon, BoatIcon, CalendarIcon } from './assets';
|
|
29
|
-
import { tealiumTrackingHandler } from '../../helpers/tracking/TrackingHandler';
|
|
30
|
-
import { getDeviceType } from './helpers';
|
|
31
29
|
|
|
32
30
|
export const TripCard: FC<TripCardProps> = ({
|
|
33
31
|
card,
|
|
34
32
|
isStaticGrid,
|
|
35
|
-
imgHeight = {}
|
|
36
|
-
source
|
|
33
|
+
imgHeight = {}
|
|
37
34
|
}) => {
|
|
38
35
|
const [imageLoaded, setImageLoaded] = useState(false);
|
|
39
|
-
const deviceType = getDeviceType();
|
|
40
|
-
console.log('source in TripCard:', source);
|
|
41
|
-
const trackEvent = (
|
|
42
|
-
eventName: string,
|
|
43
|
-
parentName: string,
|
|
44
|
-
sectionDetails: string
|
|
45
|
-
) => {
|
|
46
|
-
tealiumTrackingHandler(
|
|
47
|
-
eventName,
|
|
48
|
-
'navigation',
|
|
49
|
-
'click',
|
|
50
|
-
parentName,
|
|
51
|
-
sectionDetails,
|
|
52
|
-
{
|
|
53
|
-
device_type: deviceType,
|
|
54
|
-
source_page: source || 'unknown'
|
|
55
|
-
}
|
|
56
|
-
);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const handleCardClick = () =>
|
|
60
|
-
trackEvent('travel card selected', card.headline, 'trip cards');
|
|
61
|
-
|
|
62
|
-
const handleCTAClick = () =>
|
|
63
|
-
trackEvent(
|
|
64
|
-
'trip card cta clicked',
|
|
65
|
-
card.headline,
|
|
66
|
-
card.cta_text || 'View Itinerary'
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
const handleLogoClick = () =>
|
|
70
|
-
trackEvent(
|
|
71
|
-
'trip provider logo clicked',
|
|
72
|
-
card.headline,
|
|
73
|
-
`trip provider - ${card.logo_url}`
|
|
74
|
-
);
|
|
75
36
|
|
|
76
37
|
return (
|
|
77
38
|
<CardContainer>
|
|
78
|
-
<StyledLink
|
|
79
|
-
href={card.cta_url}
|
|
80
|
-
target="_blank"
|
|
81
|
-
rel="noopener noreferrer"
|
|
82
|
-
onClick={handleCardClick}
|
|
83
|
-
>
|
|
39
|
+
<StyledLink href={card.cta_url} target="_blank" rel="noopener noreferrer">
|
|
84
40
|
<ImageContainer isStaticGrid={isStaticGrid} {...imgHeight}>
|
|
85
41
|
{!imageLoaded && <Placeholder />}
|
|
86
42
|
<CardImage
|
|
@@ -100,7 +56,6 @@ export const TripCard: FC<TripCardProps> = ({
|
|
|
100
56
|
href={card.cta_url}
|
|
101
57
|
target="_blank"
|
|
102
58
|
rel="noopener noreferrer"
|
|
103
|
-
onClick={handleCardClick}
|
|
104
59
|
>
|
|
105
60
|
<Headline>{card.headline}</Headline>
|
|
106
61
|
</StyledLink>
|
|
@@ -164,7 +119,6 @@ export const TripCard: FC<TripCardProps> = ({
|
|
|
164
119
|
href={card.logo_url}
|
|
165
120
|
target="_blank"
|
|
166
121
|
rel="noopener noreferrer"
|
|
167
|
-
onClick={handleLogoClick}
|
|
168
122
|
>
|
|
169
123
|
<img src={card.logo} alt="Partner logo" />
|
|
170
124
|
</a>
|
|
@@ -176,7 +130,6 @@ export const TripCard: FC<TripCardProps> = ({
|
|
|
176
130
|
href={card.cta_url}
|
|
177
131
|
target="_blank"
|
|
178
132
|
rel="noopener noreferrer"
|
|
179
|
-
onClick={handleCTAClick}
|
|
180
133
|
>
|
|
181
134
|
{card.cta_text || 'View Itinerary'}
|
|
182
135
|
</CTAButton>
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
Title,
|
|
10
10
|
Subtitle,
|
|
11
11
|
TitleLink,
|
|
12
|
-
StaticCardsGrid
|
|
12
|
+
StaticCardsGrid,
|
|
13
|
+
StyledLink
|
|
13
14
|
} from './styles';
|
|
14
15
|
import { ChevronRightIcon } from './assets';
|
|
15
|
-
import { tealiumTrackingHandler } from '../../helpers/tracking/TrackingHandler';
|
|
16
16
|
|
|
17
17
|
export const TripCardsLayout: FC<TripCardsLayoutProps> = ({
|
|
18
18
|
element,
|
|
@@ -23,8 +23,7 @@ export const TripCardsLayout: FC<TripCardsLayoutProps> = ({
|
|
|
23
23
|
widthItemConfig,
|
|
24
24
|
maxWidthItemConfig,
|
|
25
25
|
imgHeight,
|
|
26
|
-
forceStaticGrid
|
|
27
|
-
source
|
|
26
|
+
forceStaticGrid
|
|
28
27
|
}) => {
|
|
29
28
|
const { titleurl, title, description } = element;
|
|
30
29
|
const gridRef = useRef<HTMLDivElement>(null);
|
|
@@ -76,21 +75,6 @@ export const TripCardsLayout: FC<TripCardsLayoutProps> = ({
|
|
|
76
75
|
const shouldUseCarousel =
|
|
77
76
|
(isTabletMobile && items.length >= 3) || !isStaticGrid || hasOverflow;
|
|
78
77
|
|
|
79
|
-
const onTitleClick = () => {
|
|
80
|
-
tealiumTrackingHandler(
|
|
81
|
-
'trip cards section title',
|
|
82
|
-
'navigation',
|
|
83
|
-
'click',
|
|
84
|
-
'Trip Cards',
|
|
85
|
-
title || 'trip cards section',
|
|
86
|
-
{
|
|
87
|
-
source_page: source || 'unknown'
|
|
88
|
-
}
|
|
89
|
-
);
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
console.log('source in TripCard:', source);
|
|
93
|
-
|
|
94
78
|
return (
|
|
95
79
|
<Container data-testid="trip-cards-container" {...widthContainerConfig}>
|
|
96
80
|
<TitleSection data-testid="title-section">
|
|
@@ -100,16 +84,14 @@ export const TripCardsLayout: FC<TripCardsLayoutProps> = ({
|
|
|
100
84
|
>
|
|
101
85
|
<TitleContent data-testid="title-content">
|
|
102
86
|
{titleurl ? (
|
|
103
|
-
<
|
|
87
|
+
<StyledLink
|
|
104
88
|
href={titleurl}
|
|
105
89
|
target="_blank"
|
|
106
90
|
rel="noopener noreferrer"
|
|
107
|
-
onClick={onTitleClick}
|
|
108
91
|
data-testid="trip-cards-title-link"
|
|
109
|
-
style={{ textDecoration: 'none', color: 'inherit' }}
|
|
110
92
|
>
|
|
111
93
|
<Title data-testid="trip-cards-title">{title}</Title>
|
|
112
|
-
</
|
|
94
|
+
</StyledLink>
|
|
113
95
|
) : (
|
|
114
96
|
<Title data-testid="trip-cards-title">{title}</Title>
|
|
115
97
|
)}
|
|
@@ -121,7 +103,6 @@ export const TripCardsLayout: FC<TripCardsLayoutProps> = ({
|
|
|
121
103
|
target="_blank"
|
|
122
104
|
rel="noopener noreferrer"
|
|
123
105
|
data-testid="title-link"
|
|
124
|
-
onClick={onTitleClick}
|
|
125
106
|
>
|
|
126
107
|
<ChevronRightIcon />
|
|
127
108
|
</TitleLink>
|
|
@@ -138,7 +119,6 @@ export const TripCardsLayout: FC<TripCardsLayoutProps> = ({
|
|
|
138
119
|
card={item.data}
|
|
139
120
|
isStaticGrid={true}
|
|
140
121
|
forceStaticGrid={forceStaticGrid}
|
|
141
|
-
source={source}
|
|
142
122
|
/>
|
|
143
123
|
))}
|
|
144
124
|
</StaticCardsGrid>
|
|
@@ -150,11 +130,7 @@ export const TripCardsLayout: FC<TripCardsLayoutProps> = ({
|
|
|
150
130
|
widthItemConfig={widthItemConfig}
|
|
151
131
|
maxWidthItemConfig={maxWidthItemConfig}
|
|
152
132
|
>
|
|
153
|
-
<CardComponent
|
|
154
|
-
card={item.data}
|
|
155
|
-
imgHeight={imgHeight}
|
|
156
|
-
source={source}
|
|
157
|
-
/>
|
|
133
|
+
<CardComponent card={item.data} imgHeight={imgHeight} />
|
|
158
134
|
</CarouselItem>
|
|
159
135
|
))}
|
|
160
136
|
options={{
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render, screen
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
3
|
import '@testing-library/jest-dom';
|
|
4
4
|
import { TripCardsLayout } from '../TripCardsLayout';
|
|
5
5
|
import { TripCardApiData } from '../types';
|
|
6
|
-
import { tealiumTrackingHandler } from '../../../helpers/tracking/TrackingHandler';
|
|
7
|
-
|
|
8
|
-
jest.mock('../../../helpers/tracking/TrackingHandler', () => ({
|
|
9
|
-
tealiumTrackingHandler: jest.fn()
|
|
10
|
-
}));
|
|
11
6
|
|
|
12
7
|
const mockElement = {
|
|
13
8
|
class: 'trip-cards',
|
|
@@ -38,7 +33,6 @@ global.ResizeObserver = class ResizeObserver {
|
|
|
38
33
|
|
|
39
34
|
describe('TripCardsLayout', () => {
|
|
40
35
|
beforeEach(() => {
|
|
41
|
-
jest.clearAllMocks();
|
|
42
36
|
Element.prototype.scrollTo = jest.fn();
|
|
43
37
|
|
|
44
38
|
// Mock matchMedia for each test
|
|
@@ -58,10 +52,6 @@ describe('TripCardsLayout', () => {
|
|
|
58
52
|
});
|
|
59
53
|
});
|
|
60
54
|
|
|
61
|
-
afterEach(() => {
|
|
62
|
-
jest.clearAllMocks();
|
|
63
|
-
});
|
|
64
|
-
|
|
65
55
|
describe('Rendering', () => {
|
|
66
56
|
it('renders with title and description', () => {
|
|
67
57
|
const items = [
|
|
@@ -590,80 +580,4 @@ describe('TripCardsLayout', () => {
|
|
|
590
580
|
}
|
|
591
581
|
});
|
|
592
582
|
});
|
|
593
|
-
|
|
594
|
-
describe('Tracking', () => {
|
|
595
|
-
it('calls tealiumTrackingHandler when title link is clicked', () => {
|
|
596
|
-
const items = [{ id: '1', data: undefined }];
|
|
597
|
-
|
|
598
|
-
render(
|
|
599
|
-
<TripCardsLayout
|
|
600
|
-
element={mockElement}
|
|
601
|
-
items={items}
|
|
602
|
-
CardComponent={MockCard}
|
|
603
|
-
itemsPerPage={2}
|
|
604
|
-
/>
|
|
605
|
-
);
|
|
606
|
-
|
|
607
|
-
const titleLink = screen.getByTestId('trip-cards-title-link');
|
|
608
|
-
fireEvent.click(titleLink);
|
|
609
|
-
|
|
610
|
-
expect(tealiumTrackingHandler).toHaveBeenCalledWith(
|
|
611
|
-
'trip cards section title',
|
|
612
|
-
'navigation',
|
|
613
|
-
'click',
|
|
614
|
-
'Trip Cards',
|
|
615
|
-
'Test Cruises',
|
|
616
|
-
{
|
|
617
|
-
source_page: 'unknown'
|
|
618
|
-
}
|
|
619
|
-
);
|
|
620
|
-
});
|
|
621
|
-
|
|
622
|
-
it('calls tealiumTrackingHandler when icon link is clicked', () => {
|
|
623
|
-
const items = [{ id: '1', data: undefined }];
|
|
624
|
-
|
|
625
|
-
render(
|
|
626
|
-
<TripCardsLayout
|
|
627
|
-
element={mockElement}
|
|
628
|
-
items={items}
|
|
629
|
-
CardComponent={MockCard}
|
|
630
|
-
itemsPerPage={2}
|
|
631
|
-
/>
|
|
632
|
-
);
|
|
633
|
-
|
|
634
|
-
const iconLink = screen.getByTestId('title-link');
|
|
635
|
-
fireEvent.click(iconLink);
|
|
636
|
-
|
|
637
|
-
expect(tealiumTrackingHandler).toHaveBeenCalledWith(
|
|
638
|
-
'trip cards section title',
|
|
639
|
-
'navigation',
|
|
640
|
-
'click',
|
|
641
|
-
'Trip Cards',
|
|
642
|
-
'Test Cruises',
|
|
643
|
-
{
|
|
644
|
-
source_page: 'unknown'
|
|
645
|
-
}
|
|
646
|
-
);
|
|
647
|
-
});
|
|
648
|
-
|
|
649
|
-
it('does not call tealiumTrackingHandler when title link is not clicked', () => {
|
|
650
|
-
const elementWithoutLink = {
|
|
651
|
-
...mockElement,
|
|
652
|
-
titleurl: undefined
|
|
653
|
-
};
|
|
654
|
-
|
|
655
|
-
const items = [{ id: '1', data: undefined }];
|
|
656
|
-
|
|
657
|
-
render(
|
|
658
|
-
<TripCardsLayout
|
|
659
|
-
element={elementWithoutLink}
|
|
660
|
-
items={items}
|
|
661
|
-
CardComponent={MockCard}
|
|
662
|
-
itemsPerPage={2}
|
|
663
|
-
/>
|
|
664
|
-
);
|
|
665
|
-
|
|
666
|
-
expect(tealiumTrackingHandler).not.toHaveBeenCalled();
|
|
667
|
-
});
|
|
668
|
-
});
|
|
669
583
|
});
|
|
@@ -117,37 +117,6 @@ export const defaultTripCardImgHeight = {
|
|
|
117
117
|
$heightXl: '245px'
|
|
118
118
|
};
|
|
119
119
|
|
|
120
|
-
export const getDeviceType = (): string => {
|
|
121
|
-
if (typeof window === 'undefined' || !window.navigator) {
|
|
122
|
-
return 'unknown';
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const userAgent = window.navigator.userAgent || '';
|
|
126
|
-
|
|
127
|
-
if (!userAgent) {
|
|
128
|
-
return 'unknown agent';
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (
|
|
132
|
-
/iPad/i.test(userAgent) ||
|
|
133
|
-
/NestHub/i.test(userAgent) ||
|
|
134
|
-
(/Android/i.test(userAgent) && !/Mobile/i.test(userAgent))
|
|
135
|
-
) {
|
|
136
|
-
return 'tablet';
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const agent = userAgent.toLowerCase();
|
|
140
|
-
const isMobile = /mobile|android|iphone|ipod|blackberry|opera mini|iemobile|windows phone/.test(
|
|
141
|
-
agent
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
if (isMobile) {
|
|
145
|
-
return 'mobile';
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return 'desktop';
|
|
149
|
-
};
|
|
150
|
-
|
|
151
120
|
const isValidOffer = (result: ApiCruiseResult): boolean => {
|
|
152
121
|
if (result.departs) {
|
|
153
122
|
const departDate = new Date(result.departs);
|
|
@@ -13,8 +13,7 @@ export const TripCards: FC<TripCardsProps> = ({
|
|
|
13
13
|
widthItemConfig,
|
|
14
14
|
maxWidthItemConfig,
|
|
15
15
|
imgHeight,
|
|
16
|
-
forceStaticGrid
|
|
17
|
-
source
|
|
16
|
+
forceStaticGrid
|
|
18
17
|
}) => {
|
|
19
18
|
const [cards, setCards] = useState<TripCardApiData[]>([]);
|
|
20
19
|
const [loading, setLoading] = useState(true);
|
|
@@ -89,7 +88,6 @@ export const TripCards: FC<TripCardsProps> = ({
|
|
|
89
88
|
maxWidthItemConfig={maxWidthItemConfig}
|
|
90
89
|
imgHeight={imgHeight}
|
|
91
90
|
forceStaticGrid={forceStaticGrid}
|
|
92
|
-
source={source}
|
|
93
91
|
/>
|
|
94
92
|
);
|
|
95
93
|
}
|
|
@@ -114,7 +112,6 @@ export const TripCards: FC<TripCardsProps> = ({
|
|
|
114
112
|
maxWidthItemConfig={maxWidthItemConfig}
|
|
115
113
|
imgHeight={imgHeight}
|
|
116
114
|
forceStaticGrid={forceStaticGrid}
|
|
117
|
-
source={source}
|
|
118
115
|
/>
|
|
119
116
|
);
|
|
120
117
|
};
|
|
@@ -35,7 +35,6 @@ export interface TripCardsProps {
|
|
|
35
35
|
maxWidthItemConfig?: ResponsiveConfig;
|
|
36
36
|
imgHeight?: ImageHeightConfig;
|
|
37
37
|
forceStaticGrid?: boolean;
|
|
38
|
-
source?: string;
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
export interface DecodedTripCard {
|
|
@@ -64,7 +63,6 @@ export interface TripCardProps {
|
|
|
64
63
|
card: TripCardApiData;
|
|
65
64
|
isStaticGrid?: boolean;
|
|
66
65
|
imgHeight?: ImageHeightConfig;
|
|
67
|
-
source?: string;
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
export interface ApiCruiseResult {
|
|
@@ -119,7 +117,6 @@ export interface TripCardsLayoutProps {
|
|
|
119
117
|
maxWidthItemConfig?: ResponsiveConfig;
|
|
120
118
|
imgHeight?: ImageHeightConfig;
|
|
121
119
|
forceStaticGrid?: boolean;
|
|
122
|
-
source?: string;
|
|
123
120
|
}
|
|
124
121
|
|
|
125
122
|
export type ImageContainerProps = ImageHeightConfig;
|