iceholidays-frontend 0.6.0 → 0.7.0
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.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/iceholidays/frontend/_slick-theme.scss +194 -0
- data/app/assets/stylesheets/iceholidays/frontend/_slick.scss +100 -0
- data/app/assets/stylesheets/iceholidays/frontend/application.sass.scss +56 -3
- data/app/assets/stylesheets/iceholidays/frontend/common.scss +14 -0
- data/app/assets/stylesheets/iceholidays/frontend/layout.scss +1 -1
- data/app/assets/stylesheets/iceholidays/frontend/utils/_slick_overrides.scss +3 -0
- data/app/javascript/api-services/brochure-api.service.ts +17 -0
- data/app/javascript/api-services/posts-api.service.ts +47 -0
- data/app/javascript/interfaces/blog.interface.ts +8 -0
- data/app/javascript/react/App.tsx +1 -1
- data/app/javascript/react/components/Destinations.tsx +21 -10
- data/app/javascript/react/components/Testimonials.tsx +4 -1
- data/app/javascript/react/components/shared/LocationDropdown.tsx +3 -1
- data/app/javascript/react/layouts/MainHeader.tsx +80 -32
- data/app/javascript/react/pages/BlogPage.tsx +82 -66
- data/app/javascript/react/pages/BlogShowPage.tsx +50 -35
- data/app/javascript/react/pages/ListingPage.tsx +42 -18
- data/app/javascript/react/pages/ShowPage.tsx +84 -52
- data/app/javascript/react/widgets/FilterPills.tsx +21 -18
- data/config/routes.rb +1 -1
- data/lib/iceholidays/frontend/version.rb +1 -1
- data/public/iceholidays-assets/application.css +296 -8
- data/public/iceholidays-assets/application.js +161 -121
- data/public/iceholidays-assets/application.js.map +4 -4
- data/public/iceholidays-assets/images/TST Ribbon@2x.png +0 -0
- data/public/iceholidays-assets/images/TST Ribbon@3x.png +0 -0
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 59f15f7f57f10fa3e940d7dd8d7d1793fda28e03094d4728affa3ebdbb7ddb51
|
|
4
|
+
data.tar.gz: 93cc996da24784b1ae848ee7b8ca585db5f289911968b940cf41b981b8ae2a0b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e3ba2c318d47c1e98b5a7feeca5cb95095669758d32727014327388b91f297a69929d4c0a4cac538e521dd89d87985836a3bddb29ed5707221fc1b436695f5e
|
|
7
|
+
data.tar.gz: 50191a25fab1a9471c4637ba6e709a43e094df1126bf6799a9b9e3d30eb3811beb0888c064f84ff1dbb2024c62321246bb10ab467040085a486b01fba3e9542d
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
// Default Variables
|
|
4
|
+
|
|
5
|
+
// Slick icon entity codes outputs the following
|
|
6
|
+
// "\2190" outputs ascii character "←"
|
|
7
|
+
// "\2192" outputs ascii character "→"
|
|
8
|
+
// "\2022" outputs ascii character "•"
|
|
9
|
+
|
|
10
|
+
$slick-font-path: "./fonts/" !default;
|
|
11
|
+
$slick-font-family: "slick" !default;
|
|
12
|
+
$slick-loader-path: "./" !default;
|
|
13
|
+
$slick-arrow-color: white !default;
|
|
14
|
+
$slick-dot-color: black !default;
|
|
15
|
+
$slick-dot-color-active: $slick-dot-color !default;
|
|
16
|
+
$slick-prev-character: "\2190" !default;
|
|
17
|
+
$slick-next-character: "\2192" !default;
|
|
18
|
+
$slick-dot-character: "\2022" !default;
|
|
19
|
+
$slick-dot-size: 6px !default;
|
|
20
|
+
$slick-opacity-default: 0.75 !default;
|
|
21
|
+
$slick-opacity-on-hover: 1 !default;
|
|
22
|
+
$slick-opacity-not-active: 0.25 !default;
|
|
23
|
+
|
|
24
|
+
@function slick-image-url($url) {
|
|
25
|
+
@if function-exists(image-url) {
|
|
26
|
+
@return image-url($url);
|
|
27
|
+
}
|
|
28
|
+
@else {
|
|
29
|
+
@return url($slick-loader-path + $url);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@function slick-font-url($url) {
|
|
34
|
+
@if function-exists(font-url) {
|
|
35
|
+
@return font-url($url);
|
|
36
|
+
}
|
|
37
|
+
@else {
|
|
38
|
+
@return url($slick-font-path + $url);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Slider */
|
|
43
|
+
|
|
44
|
+
// .slick-list {
|
|
45
|
+
// .slick-loading & {
|
|
46
|
+
// background: #fff slick-image-url("ajax-loader.gif") center center no-repeat;
|
|
47
|
+
// }
|
|
48
|
+
// }
|
|
49
|
+
|
|
50
|
+
/* Icons */
|
|
51
|
+
// @if $slick-font-family == "slick" {
|
|
52
|
+
// @font-face {
|
|
53
|
+
// font-family: "slick";
|
|
54
|
+
// src: slick-font-url("slick.eot");
|
|
55
|
+
// src: slick-font-url("slick.eot?#iefix") format("embedded-opentype"), slick-font-url("slick.woff") format("woff"), slick-font-url("slick.ttf") format("truetype"), slick-font-url("slick.svg#slick") format("svg");
|
|
56
|
+
// font-weight: normal;
|
|
57
|
+
// font-style: normal;
|
|
58
|
+
// }
|
|
59
|
+
// }
|
|
60
|
+
|
|
61
|
+
/* Arrows */
|
|
62
|
+
|
|
63
|
+
.slick-prev,
|
|
64
|
+
.slick-next {
|
|
65
|
+
position: absolute;
|
|
66
|
+
display: block;
|
|
67
|
+
height: 20px;
|
|
68
|
+
width: 20px;
|
|
69
|
+
line-height: 0px;
|
|
70
|
+
font-size: 0px;
|
|
71
|
+
cursor: pointer;
|
|
72
|
+
background: transparent;
|
|
73
|
+
color: transparent;
|
|
74
|
+
top: 50%;
|
|
75
|
+
-webkit-transform: translate(0, -50%);
|
|
76
|
+
-ms-transform: translate(0, -50%);
|
|
77
|
+
transform: translate(0, -50%);
|
|
78
|
+
padding: 0;
|
|
79
|
+
border: none;
|
|
80
|
+
outline: none;
|
|
81
|
+
&:hover, &:focus {
|
|
82
|
+
outline: none;
|
|
83
|
+
background: transparent;
|
|
84
|
+
color: transparent;
|
|
85
|
+
&:before {
|
|
86
|
+
opacity: $slick-opacity-on-hover;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
&.slick-disabled:before {
|
|
90
|
+
opacity: $slick-opacity-not-active;
|
|
91
|
+
}
|
|
92
|
+
&:before {
|
|
93
|
+
font-family: $slick-font-family;
|
|
94
|
+
font-size: 20px;
|
|
95
|
+
line-height: 1;
|
|
96
|
+
color: $slick-arrow-color;
|
|
97
|
+
opacity: $slick-opacity-default;
|
|
98
|
+
-webkit-font-smoothing: antialiased;
|
|
99
|
+
-moz-osx-font-smoothing: grayscale;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.slick-prev {
|
|
104
|
+
left: -25px;
|
|
105
|
+
[dir="rtl"] & {
|
|
106
|
+
left: auto;
|
|
107
|
+
right: -25px;
|
|
108
|
+
}
|
|
109
|
+
&:before {
|
|
110
|
+
content: $slick-prev-character;
|
|
111
|
+
[dir="rtl"] & {
|
|
112
|
+
content: $slick-next-character;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.slick-next {
|
|
118
|
+
right: -25px;
|
|
119
|
+
[dir="rtl"] & {
|
|
120
|
+
left: -25px;
|
|
121
|
+
right: auto;
|
|
122
|
+
}
|
|
123
|
+
&:before {
|
|
124
|
+
content: $slick-next-character;
|
|
125
|
+
[dir="rtl"] & {
|
|
126
|
+
content: $slick-prev-character;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* Dots */
|
|
132
|
+
|
|
133
|
+
.slick-dotted.slick-slider {
|
|
134
|
+
margin-bottom: 30px;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.slick-dots {
|
|
138
|
+
position: absolute;
|
|
139
|
+
bottom: -25px;
|
|
140
|
+
list-style: none;
|
|
141
|
+
display: block;
|
|
142
|
+
text-align: center;
|
|
143
|
+
padding: 0;
|
|
144
|
+
margin: 0;
|
|
145
|
+
width: 100%;
|
|
146
|
+
li {
|
|
147
|
+
position: relative;
|
|
148
|
+
display: inline-block;
|
|
149
|
+
height: 20px;
|
|
150
|
+
width: 20px;
|
|
151
|
+
margin: 0 5px;
|
|
152
|
+
padding: 0;
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
button {
|
|
155
|
+
border: 0;
|
|
156
|
+
background: transparent;
|
|
157
|
+
display: block;
|
|
158
|
+
height: 20px;
|
|
159
|
+
width: 20px;
|
|
160
|
+
outline: none;
|
|
161
|
+
line-height: 0px;
|
|
162
|
+
font-size: 0px;
|
|
163
|
+
color: transparent;
|
|
164
|
+
padding: 5px;
|
|
165
|
+
cursor: pointer;
|
|
166
|
+
&:hover, &:focus {
|
|
167
|
+
outline: none;
|
|
168
|
+
&:before {
|
|
169
|
+
opacity: $slick-opacity-on-hover;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
&:before {
|
|
173
|
+
position: absolute;
|
|
174
|
+
top: 0;
|
|
175
|
+
left: 0;
|
|
176
|
+
content: $slick-dot-character;
|
|
177
|
+
width: 20px;
|
|
178
|
+
height: 20px;
|
|
179
|
+
font-family: $slick-font-family;
|
|
180
|
+
font-size: $slick-dot-size;
|
|
181
|
+
line-height: 20px;
|
|
182
|
+
text-align: center;
|
|
183
|
+
color: $slick-dot-color;
|
|
184
|
+
opacity: $slick-opacity-not-active;
|
|
185
|
+
-webkit-font-smoothing: antialiased;
|
|
186
|
+
-moz-osx-font-smoothing: grayscale;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
&.slick-active button:before {
|
|
190
|
+
color: $slick-dot-color-active;
|
|
191
|
+
opacity: $slick-opacity-default;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* Slider */
|
|
2
|
+
|
|
3
|
+
.slick-slider {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: block;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
-webkit-touch-callout: none;
|
|
8
|
+
-webkit-user-select: none;
|
|
9
|
+
-khtml-user-select: none;
|
|
10
|
+
-moz-user-select: none;
|
|
11
|
+
-ms-user-select: none;
|
|
12
|
+
user-select: none;
|
|
13
|
+
-ms-touch-action: pan-y;
|
|
14
|
+
touch-action: pan-y;
|
|
15
|
+
-webkit-tap-highlight-color: transparent;
|
|
16
|
+
}
|
|
17
|
+
.slick-list {
|
|
18
|
+
position: relative;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
display: block;
|
|
21
|
+
margin: 0;
|
|
22
|
+
padding: 0;
|
|
23
|
+
|
|
24
|
+
&:focus {
|
|
25
|
+
outline: none;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&.dragging {
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
cursor: hand;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
.slick-slider .slick-track,
|
|
34
|
+
.slick-slider .slick-list {
|
|
35
|
+
-webkit-transform: translate3d(0, 0, 0);
|
|
36
|
+
-moz-transform: translate3d(0, 0, 0);
|
|
37
|
+
-ms-transform: translate3d(0, 0, 0);
|
|
38
|
+
-o-transform: translate3d(0, 0, 0);
|
|
39
|
+
transform: translate3d(0, 0, 0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.slick-track {
|
|
43
|
+
position: relative;
|
|
44
|
+
left: 0;
|
|
45
|
+
top: 0;
|
|
46
|
+
display: block;
|
|
47
|
+
margin-left: auto;
|
|
48
|
+
margin-right: auto;
|
|
49
|
+
|
|
50
|
+
&:before,
|
|
51
|
+
&:after {
|
|
52
|
+
content: "";
|
|
53
|
+
display: table;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&:after {
|
|
57
|
+
clear: both;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.slick-loading & {
|
|
61
|
+
visibility: hidden;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
.slick-slide {
|
|
65
|
+
float: left;
|
|
66
|
+
height: 100%;
|
|
67
|
+
min-height: 1px;
|
|
68
|
+
[dir="rtl"] & {
|
|
69
|
+
float: right;
|
|
70
|
+
}
|
|
71
|
+
img {
|
|
72
|
+
display: block;
|
|
73
|
+
}
|
|
74
|
+
&.slick-loading img {
|
|
75
|
+
display: none;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
display: none;
|
|
79
|
+
|
|
80
|
+
&.dragging img {
|
|
81
|
+
pointer-events: none;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.slick-initialized & {
|
|
85
|
+
display: block;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.slick-loading & {
|
|
89
|
+
visibility: hidden;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.slick-vertical & {
|
|
93
|
+
display: block;
|
|
94
|
+
height: auto;
|
|
95
|
+
border: 1px solid transparent;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
.slick-arrow.slick-hidden {
|
|
99
|
+
display: none;
|
|
100
|
+
}
|
|
@@ -15,8 +15,11 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
@import url("//fonts.googleapis.com/css?family=Poppins:ital,wght@0,100;0,200;0,200;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,200;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
|
|
18
|
+
@import "_slick.scss";
|
|
19
|
+
@import "_slick-theme.scss";
|
|
18
20
|
@import "utils/_variables.scss";
|
|
19
21
|
@import "utils/_antd_overrides.scss";
|
|
22
|
+
@import "utils/_slick_overrides.scss";
|
|
20
23
|
@import "layout.scss";
|
|
21
24
|
@import "common.scss";
|
|
22
25
|
@import "widgets/search_bar.scss";
|
|
@@ -608,7 +611,7 @@ body{
|
|
|
608
611
|
#date-selector{
|
|
609
612
|
padding: 20px var(--side-padding);
|
|
610
613
|
|
|
611
|
-
[class~='
|
|
614
|
+
[class~='slick-slider'] {
|
|
612
615
|
.slick-slide > div{
|
|
613
616
|
padding: 0 5px;
|
|
614
617
|
}
|
|
@@ -622,11 +625,11 @@ body{
|
|
|
622
625
|
}
|
|
623
626
|
|
|
624
627
|
.slick-prev{
|
|
625
|
-
inset-inline-start: -
|
|
628
|
+
inset-inline-start: -35px;
|
|
626
629
|
}
|
|
627
630
|
|
|
628
631
|
.slick-next{
|
|
629
|
-
inset-inline-end: -
|
|
632
|
+
inset-inline-end: -35px;
|
|
630
633
|
}
|
|
631
634
|
}
|
|
632
635
|
.date-box{
|
|
@@ -1172,6 +1175,10 @@ body{
|
|
|
1172
1175
|
display: block;
|
|
1173
1176
|
}
|
|
1174
1177
|
|
|
1178
|
+
picture > img{
|
|
1179
|
+
width: 100%;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1175
1182
|
#about-st-feature{
|
|
1176
1183
|
|
|
1177
1184
|
#feature{
|
|
@@ -1659,6 +1666,19 @@ body{
|
|
|
1659
1666
|
|
|
1660
1667
|
#blogs{
|
|
1661
1668
|
margin: 30px 0;
|
|
1669
|
+
|
|
1670
|
+
.preview-content{
|
|
1671
|
+
overflow: hidden;
|
|
1672
|
+
text-overflow: ellipsis;
|
|
1673
|
+
display: -webkit-box;
|
|
1674
|
+
-webkit-line-clamp: 2;
|
|
1675
|
+
-webkit-box-orient: vertical;
|
|
1676
|
+
max-height: 100px;
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
.view-blog{
|
|
1680
|
+
margin-top: 10px;
|
|
1681
|
+
}
|
|
1662
1682
|
}
|
|
1663
1683
|
}
|
|
1664
1684
|
}
|
|
@@ -1670,6 +1690,23 @@ body{
|
|
|
1670
1690
|
border-radius: 20px;
|
|
1671
1691
|
background: rgba(255, 255, 255, 1);
|
|
1672
1692
|
box-shadow: 0px 5px 20px 0px rgba(225, 182, 91, 0.2);
|
|
1693
|
+
|
|
1694
|
+
h1{
|
|
1695
|
+
font-family: Poppins;
|
|
1696
|
+
font-weight: 600;
|
|
1697
|
+
font-size: 24px;
|
|
1698
|
+
line-height: 36px;
|
|
1699
|
+
letter-spacing: 0%;
|
|
1700
|
+
margin-top: 0;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
img{
|
|
1704
|
+
object-fit: cover;
|
|
1705
|
+
height: auto;
|
|
1706
|
+
border-radius: 20px;
|
|
1707
|
+
width: 100%;
|
|
1708
|
+
margin-bottom: 20px;
|
|
1709
|
+
}
|
|
1673
1710
|
}
|
|
1674
1711
|
|
|
1675
1712
|
}
|
|
@@ -2059,6 +2096,22 @@ body{
|
|
|
2059
2096
|
}
|
|
2060
2097
|
}
|
|
2061
2098
|
|
|
2099
|
+
#date-selector{
|
|
2100
|
+
[class~='slick-slider'] {
|
|
2101
|
+
.slick-slide > div{
|
|
2102
|
+
padding: 0 5px;
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
.slick-prev{
|
|
2106
|
+
inset-inline-start: -40px;
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
.slick-next{
|
|
2110
|
+
inset-inline-end: -40px;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2062
2115
|
&_body{
|
|
2063
2116
|
.toggle_contact-agent,
|
|
2064
2117
|
.collapse-contact-agent{
|
|
@@ -315,4 +315,18 @@
|
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
@media only screen and (min-width: 1441px) {
|
|
321
|
+
#ribbon-section_header{
|
|
322
|
+
background-image: url('/iceholidays-assets/images/TST Ribbon@2x.png');
|
|
323
|
+
height: 300px;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
@media only screen and (min-width: 2880px) {
|
|
328
|
+
#ribbon-section_header{
|
|
329
|
+
background-image: url('/iceholidays-assets/images/TST Ribbon@3x.png');
|
|
330
|
+
height: 450px;
|
|
331
|
+
}
|
|
318
332
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
|
|
3
|
+
class BrochueApi {
|
|
4
|
+
|
|
5
|
+
getBrochure(): Promise<string> {
|
|
6
|
+
const apiUrl = "/api/v1/brochure";
|
|
7
|
+
|
|
8
|
+
return axios.get(apiUrl)
|
|
9
|
+
.then(response => {
|
|
10
|
+
const brochureUrl = response.data.url;
|
|
11
|
+
return Promise.resolve(brochureUrl);
|
|
12
|
+
})
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default BrochueApi;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { Blog } from "../interfaces/blog.interface";
|
|
3
|
+
|
|
4
|
+
class PostsApi {
|
|
5
|
+
|
|
6
|
+
getBlogs(): Promise<Blog[]> {
|
|
7
|
+
const apiUrl = "/api/v1/posts";
|
|
8
|
+
|
|
9
|
+
return axios.get(apiUrl)
|
|
10
|
+
.then(response => {
|
|
11
|
+
const blogs = response.data.data.map(postData => {
|
|
12
|
+
const post:Blog = {
|
|
13
|
+
id: postData.attributes.id,
|
|
14
|
+
title: postData.attributes.title,
|
|
15
|
+
thumbnail: postData.attributes.thumbnail,
|
|
16
|
+
content: postData.attributes.body,
|
|
17
|
+
// author: postData.attributes.author,
|
|
18
|
+
// createdOn: postData.attributes.created_on,
|
|
19
|
+
}
|
|
20
|
+
return post;
|
|
21
|
+
})
|
|
22
|
+
return Promise.resolve(blogs);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
getBlog(blogId:number): Promise<Blog> {
|
|
28
|
+
const apiUrl = `/api/v1/posts/${blogId}`;
|
|
29
|
+
|
|
30
|
+
return axios.get(apiUrl)
|
|
31
|
+
.then(response => {
|
|
32
|
+
const postData = response.data.data.attributes;
|
|
33
|
+
const post:Blog = {
|
|
34
|
+
id: response.data.data.id,
|
|
35
|
+
title: postData.title,
|
|
36
|
+
thumbnail: postData.thumbnail,
|
|
37
|
+
content: postData.body,
|
|
38
|
+
// author: postData.author,
|
|
39
|
+
// createdOn: postData.created_on,
|
|
40
|
+
}
|
|
41
|
+
return Promise.resolve(post);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default PostsApi;
|
|
@@ -22,7 +22,7 @@ export default function App() {
|
|
|
22
22
|
<Route path="/app/about-us" element={<AboutUsPage />} />
|
|
23
23
|
<Route path="/app/countries" element={<CountriesPage />} />
|
|
24
24
|
<Route path="/app/blog" element={<BlogPage />} />
|
|
25
|
-
<Route path="/app/blog
|
|
25
|
+
<Route path="/app/blog/:id" element={<BlogShowPage />} />
|
|
26
26
|
<Route path="/app/contact-agents" element={<ContactAgentsPage />} />
|
|
27
27
|
<Route path="/app/contact-us" element={<ContactUsPage />} />
|
|
28
28
|
</Route>
|
|
@@ -1,32 +1,47 @@
|
|
|
1
|
-
import { notification,
|
|
1
|
+
import { notification, Tabs, TabsProps } from "antd";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import LocationsApi from "../../api-services/locations-api.service";
|
|
4
4
|
import { Country } from "../../interfaces/country.interface";
|
|
5
|
-
import {
|
|
5
|
+
import { mdiMenuRight } from "@mdi/js";
|
|
6
6
|
import Icon from "@mdi/react";
|
|
7
7
|
import { Link } from "react-router-dom";
|
|
8
8
|
import LocationPostcards from "./shared/LocationPostcards";
|
|
9
9
|
import LocationDropdown from "./shared/LocationDropdown";
|
|
10
10
|
|
|
11
|
+
interface IDestinationState {
|
|
12
|
+
countries: Country[],
|
|
13
|
+
selectedCountry: any,
|
|
14
|
+
activeTab: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
|
|
12
18
|
export default class Destinations extends React.Component {
|
|
13
19
|
api = new LocationsApi;
|
|
14
20
|
|
|
15
|
-
state = {
|
|
21
|
+
state:IDestinationState = {
|
|
16
22
|
countries: [],
|
|
23
|
+
selectedCountry: {},
|
|
17
24
|
activeTab: "1"
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
componentDidMount() {
|
|
21
28
|
this.api.getCountries()
|
|
22
29
|
.then(locationsData => {
|
|
23
|
-
this.setState({countries: locationsData})
|
|
30
|
+
this.setState({countries: locationsData, selectedCountry: locationsData[0]})
|
|
24
31
|
})
|
|
25
32
|
.catch(error => {
|
|
26
33
|
notification.error({ message: 'An error occured while loading countries.'});
|
|
27
34
|
});
|
|
28
35
|
}
|
|
29
36
|
|
|
37
|
+
changeTab (selectedCountryId) {
|
|
38
|
+
const countries = this.state.countries;
|
|
39
|
+
const selectedCountry = countries.find(c => c.id == +selectedCountryId);
|
|
40
|
+
if(selectedCountry) this.setState({selectedCountry});
|
|
41
|
+
|
|
42
|
+
this.setState({activeTab:selectedCountryId.toString()})
|
|
43
|
+
}
|
|
44
|
+
|
|
30
45
|
render(){
|
|
31
46
|
const pluralize = (count: number, noun: string, suffix = 's') =>
|
|
32
47
|
`${count} ${noun}${count > 1 ? suffix : ''}`;
|
|
@@ -35,10 +50,6 @@ export default class Destinations extends React.Component {
|
|
|
35
50
|
return `/app/listing?location_id=${locationId}`;
|
|
36
51
|
}
|
|
37
52
|
|
|
38
|
-
const changeTab = (selectedKey:string) => {
|
|
39
|
-
this.setState({activeTab:selectedKey.toString()})
|
|
40
|
-
}
|
|
41
|
-
|
|
42
53
|
|
|
43
54
|
var items:TabsProps["items"] = this.state.countries.map((country:Country, index)=>{
|
|
44
55
|
return {
|
|
@@ -102,14 +113,14 @@ export default class Destinations extends React.Component {
|
|
|
102
113
|
<div id="popular-destinations">
|
|
103
114
|
<h1>Explore Popular Destination</h1>
|
|
104
115
|
|
|
105
|
-
<LocationDropdown locations={this.state.countries} selectLocation={changeTab}/>
|
|
116
|
+
<LocationDropdown initialValue={this.state.selectedCountry?.name} locations={this.state.countries} selectLocation={(selected)=>this.changeTab(selected)}/>
|
|
106
117
|
|
|
107
118
|
<Tabs
|
|
108
119
|
defaultActiveKey="1"
|
|
109
120
|
activeKey={this.state.activeTab}
|
|
110
121
|
items={items}
|
|
111
122
|
type="card"
|
|
112
|
-
onChange={changeTab}/>
|
|
123
|
+
onChange={(selected)=>this.changeTab(selected)}/>
|
|
113
124
|
|
|
114
125
|
</div>
|
|
115
126
|
)
|
|
@@ -7,6 +7,9 @@ import RibbonSection from "./shared/RibbonSection";
|
|
|
7
7
|
import TestimonialsApi from "../../api-services/testimonials-api.service";
|
|
8
8
|
import { Testimonial } from "../../interfaces/testimonial.interface";
|
|
9
9
|
import createDOMPurify from 'dompurify'
|
|
10
|
+
import Markdown from "react-markdown";
|
|
11
|
+
import rehypeRaw from "rehype-raw";
|
|
12
|
+
import remarkGfm from "remark-gfm";
|
|
10
13
|
|
|
11
14
|
const DOMPurify = createDOMPurify(window)
|
|
12
15
|
|
|
@@ -54,7 +57,7 @@ export default class Testimonials extends React.Component {
|
|
|
54
57
|
</div>
|
|
55
58
|
</div>
|
|
56
59
|
<div className="comment">
|
|
57
|
-
<
|
|
60
|
+
<Markdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>{review.comment}</Markdown>
|
|
58
61
|
</div>
|
|
59
62
|
<div className="author">
|
|
60
63
|
<Icon path={mdiFountainPenTip} size={1} className="author-icon" />
|
|
@@ -8,10 +8,11 @@ import { mdiFilterVariant } from "@mdi/js";
|
|
|
8
8
|
const LocationDropdown = (
|
|
9
9
|
props: {
|
|
10
10
|
locations:Location[];
|
|
11
|
+
initialValue:string;
|
|
11
12
|
selectLocation;
|
|
12
13
|
}
|
|
13
14
|
) => {
|
|
14
|
-
const { locations } = props;
|
|
15
|
+
const { locations, initialValue } = props;
|
|
15
16
|
|
|
16
17
|
return (
|
|
17
18
|
<div className="location-dropdown">
|
|
@@ -20,6 +21,7 @@ const LocationDropdown = (
|
|
|
20
21
|
suffixIcon={<Icon path={mdiFilterVariant} size="18px" />}
|
|
21
22
|
variant="borderless"
|
|
22
23
|
defaultValue="china"
|
|
24
|
+
value={initialValue}
|
|
23
25
|
options={locations.map((location) => ({label: location.name, value: location.id}))}
|
|
24
26
|
dropdownStyle={{padding: "15px 20px", borderRadius: "20px", boxShadow: "0px 3.08px 16.47px 0px #00000040"}}
|
|
25
27
|
optionRender={(option) => (
|