1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
2 @functions {
3 string GetCustomField(Dynamicweb.Security.UserManagement.User user, string fieldName)
4 {
5 string? fieldValue = user.CustomFieldValues
6 .FirstOrDefault(a => a.CustomField.SystemName == fieldName)?
7 .Value?
8 .ToString()?
9 .Trim();
10 return $"{fieldValue}";
11 }
12 }
13 @{
14
15 string apiKey = !string.IsNullOrEmpty(Pageview.AreaSettings.GetString("Google_APIKey")) ? Pageview.AreaSettings.GetString("Google_APIKey") : "";
16 var UserGroup = Model.Item.GetString("UserGroup");
17 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/";
18 string markerPath = "/Files/Templates/Designs/Swift/Assets/markers/";
19 int initialZoomLevel = !string.IsNullOrEmpty(Model.Item.GetString("InitialZoomLevel")) ? Model.Item.GetInt32("InitialZoomLevel") : 4;
20 initialZoomLevel = initialZoomLevel == 0 ? 4 : initialZoomLevel;
21 string regionCode = !string.IsNullOrEmpty(Model.Item.GetString("RegionCode")) ? Model.Item.GetString("RegionCode") : "DK";
22 bool useDefaultGoogleMapsStyling = !string.IsNullOrEmpty(Model.Item.GetString("UseDefaultGoogleMapsStyling")) ? Model.Item.GetBoolean("UseDefaultGoogleMapsStyling") : false;
23
24 var defaultLat = Model.Item?.GetGeolocation("DefaultMapCenter")?.Latitude != null ? Model.Item.GetGeolocation("DefaultMapCenter").Latitude.ToString().Replace(",", ".") : "0.000000";
25 var defaultLng = Model.Item?.GetGeolocation("DefaultMapCenter")?.Longitude != null ? Model.Item.GetGeolocation("DefaultMapCenter").Longitude.ToString().Replace(",", ".") : "0.000000";
26 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
27
28 string headingLevel = Model.Item.GetString("HeadingLevel", "h2");
29 string headingLevelStart = $"<{headingLevel} class=\"h1 m-0\">";
30 string headingLevelStop = $"</{headingLevel}>";
31
32 string HighlightColor = Model.Item.GetString("HighlightColor");
33 string ClusterColor = Model.Item.GetString("ClusterColor");
34 string BrandName = Model.Item.GetString("Brand", "");
35 var ShowByField = BrandName switch
36 {
37 "outwell" => "AccessUser_DisplayOutwell",
38 "robens" => "AccessUser_DisplayRobens",
39 "easy-camp" => "AccessUser_DisplayEasycamp",
40 _ => ""
41 };
42 var WebsiteField = BrandName switch
43 {
44 "outwell" => "AccessUser_WebsiteURLOutwell",
45 "robens" => "AccessUser_WebsiteURLRobens",
46 "easy-camp" => "AccessUser_WebsiteURLEasycamp",
47 _ => ""
48 };
49
50 // BUTTONS
51 // Primary
52 string DealersButton = Model.Item.GetString("PrimaryText", "");
53 string DealersButtonIcon = Model.Item.GetString("PrimaryIcon", "");
54 string DealersButtonMarker = Model.Item.GetString("PrimaryMarker", "");
55
56 // Tents
57 string TentButton = Model.Item.GetString("TentText", ""); ;
58 string TentButtonIcon = Model.Item.GetString("TentIcon", "");
59 string TentButtonMarker = Model.Item.GetString("TentMarker", "");
60 // Tents showroom
61 string TentShowroomButton = Model.Item.GetString("TentShowroomText", "");
62 string TentShowroomButtonIcon = Model.Item.GetString("TentShowroomIcon", "");
63 string TentShowroomButtonMarker = Model.Item.GetString("TentShowroomMarker", "");
64 // Awnings
65 string AwningButton = Model.Item.GetString("AwningText", "");
66 string AwningButtonIcon = Model.Item.GetString("AwningIcon", "");
67 string AwningButtonMarker = Model.Item.GetString("AwningMarker", "");
68 // Awnings showroom
69 string AwningShowroomButton = Model.Item.GetString("AwningShowroomText", "");
70 string AwningShowroomButtonIcon = Model.Item.GetString("AwningShowroomIcon", "");
71 string AwningShowroomButtonMarker = Model.Item.GetString("AwningShowroomMarker", "");
72
73
74 string ActiveButtonColor = Model.Item.GetString("ActiveButtonColor", "#f8f8f8");
75
76 // User group
77 UserGroup = UserGroup.Replace("[", "").Replace("]", "").Trim();
78 var UserGroupId = int.TryParse(UserGroup, out int GroupId);
79
80 List<Dynamicweb.Security.UserManagement.User> locationList = new();
81 if (GroupId != 0)
82 {
83 locationList = new Dynamicweb.Security.UserManagement.UserService().GetUsersByGroupId(GroupId).ToList();
84 List<Dynamicweb.Security.UserManagement.User> filteredLocationList = new();
85 foreach (var item in locationList)
86 {
87 if (!string.IsNullOrWhiteSpace(ShowByField))
88 {
89 string ShowOnThisBrand = GetCustomField(item, ShowByField);
90 if (ShowOnThisBrand == "1" || ShowOnThisBrand == "2")
91 {
92 filteredLocationList.Add(item);
93 }
94 }
95 }
96 locationList = filteredLocationList;
97 }
98
99 string ProductId = Dynamicweb.Context.Current.Request.QueryString.Get("p");
100
101 // Handle OLD url, that had parameter ProductID
102 string ProductIdOLD = Dynamicweb.Context.Current.Request.QueryString.Get("ProductID");
103 if (!string.IsNullOrWhiteSpace(ProductIdOLD))
104 {
105 Dynamicweb.Context.Current.Response.Redirect(Pageview.SearchFriendlyUrl.ToLower().Replace("productid", "p"));
106 }
107
108 if (!string.IsNullOrWhiteSpace(ProductId))
109 {
110 var ProductSpecific = Dynamicweb.Ecommerce.Services.Products.GetProductById(ProductId, "", Pageview.Area.EcomLanguageId);
111 if (ProductSpecific != null)
112 {
113 var Assortments = ProductSpecific.ProductFieldValues.GetProductFieldValue("Assortment")?.Value.ToString();
114 var AssortmentIds = Assortments?.Replace(" ", "").Split(",");
115 if (!string.IsNullOrWhiteSpace(Assortments))
116 {
117 locationList = locationList.Where(a => AssortmentIds.Contains(a.CustomerNumber.Trim())).ToList();
118
119 var Image001 = ProductSpecific.ProductFieldValues.GetProductFieldValue("Image001")?.Value.ToString();
120 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(Image001);
121 string imagePath = "/Admin/Public/GetImage.ashx?width=1200&image=/files/images/products/" + imagePathUrlEncoded + ".png&format=webp";
122
123 <div class="row">
124 <div class="col-12 col-md-4">
125 <div class="ratio-4x3" style="max-width:200px;">
126 <img id="@imagePath"
127 src="@imagePath"
128 loading="lazy"
129 decoding="async"
130 class="h-100 w-100"
131 style="object-fit: cover;"
132 alt="@ProductSpecific.Name">
133 </div>
134 <p class="h4">@ProductSpecific.Name</p>
135 </div>
136 <div class="col-12 col-md-4"></div>
137 <div class="col-12 col-md-4"></div>
138 </div>
139
140 }
141 }
142 }
143 }
144 <style>
145 .stores-wrap::-webkit-scrollbar {
146 width: 10px;
147 }
148
149 .stores-wrap::-webkit-scrollbar-track {
150 background: #f1f1f1;
151 }
152
153 .stores-wrap::-webkit-scrollbar-thumb {
154 background: @(HighlightColor);
155 }
156 .store.highlight {
157 background-color: #f8f8f8;
158 }
159 .cluster-marker {
160 width: 40px;
161 height: 40px;
162 background-color: @(ClusterColor);
163 color: white;
164 border-radius: 50%;
165 display: flex;
166 justify-content: center;
167 align-items: center;
168 font-size: 14px;
169 font-weight: bold;
170 border: 2px solid white;
171 box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3);
172 }
173
174 #toggle-buttons button {
175 min-width: 150px;
176 text-align: left;
177 }
178 #toggle-buttons button.active {
179 background-color: @(ActiveButtonColor) !important;
180 }
181 </style>
182
183 @if (apiKey != "")
184 {
185 <div class="grid position-relative@(theme)
[email protected]()">
186 <div id="@Model.ID" class="user-select-none position-absolute" style="scroll-margin-top:var(--header-height,150px)"></div>
187
188 <div class="g-col-12 order-1 order-lg-2 position-relative">
189 <div id="toggle-buttons" class="d-flex flex-wrap justify-content-lg-end gap-3">
190
191 @if (!string.IsNullOrWhiteSpace(TentButton))
192 {
193 <button type="button" id="toggle-tent" class="btn border rounded-0 p-2 px-lg-3 text-nowrap fs-8 fs-lg-6">
194 <img src="@(TentButtonIcon)" height="32" class="d-none d-lg-inline me-2" />
195 <img src="@(TentButtonIcon)" height="24" class="d-inline d-lg-none me-2" />
196 @TentButton
197 </button>
198 }
199 @if (!string.IsNullOrWhiteSpace(TentShowroomButton))
200 {
201 <button type="button" id="toggle-tentshowroom" class="btn border rounded-0 p-2 px-lg-3 text-nowrap fs-8 fs-lg-6">
202 <img src="@(TentShowroomButtonIcon)" height="32" class="d-none d-lg-inline me-2" />
203 <img src="@(TentShowroomButtonIcon)" height="24" class="d-inline d-lg-none me-2" />
204 @TentShowroomButton
205 </button>
206 }
207 @if (!string.IsNullOrWhiteSpace(AwningButton))
208 {
209 <button type="button" id="toggle-awning" class="btn border rounded-0 p-2 px-lg-3 text-nowrap fs-8 fs-lg-6">
210 <img src="@(AwningButtonIcon)" height="32" class="d-none d-lg-inline me-2" />
211 <img src="@(AwningButtonIcon)" height="24" class="d-inline d-lg-none me-2" />
212 @AwningButton
213 </button>
214 }
215 @if (!string.IsNullOrWhiteSpace(AwningShowroomButton))
216 {
217 <button type="button" id="toggle-awningshowroom" class="btn border rounded-0 p-2 px-lg-3 text-nowrap fs-8 fs-lg-6">
218 <img src="@(AwningShowroomButtonIcon)" height="32" class="d-none d-lg-inline me-2" />
219 <img src="@(AwningShowroomButtonIcon)" height="24" class="d-inline d-lg-none me-2" />
220 @AwningShowroomButton
221 </button>
222 }
223 @if (!string.IsNullOrWhiteSpace(DealersButton))
224 {
225 <button type="button" id="toggle-stores" class="btn border rounded-0 p-2 px-lg-3 text-nowrap fs-8 fs-lg-6 active">
226 <img src="@(DealersButtonIcon)" height="32" class="d-none d-lg-inline me-2" />
227 <img src="@(DealersButtonIcon)" height="24" class="d-inline d-lg-none me-2" />
228 @DealersButton
229 </button>
230 }
231 </div>
232 </div>
233
234 <div class="g-col-12 g-col-lg-8 order-1 order-lg-4">
235 <div class="map" id="map"></div>
236 </div>
237
238 @if (locationList.Count() >= 1)
239 {
240 <div class="g-col-12 g-col-lg-4 order-2 order-lg-3">
241 <div class="d-flex align-items-center mb-3">
242 <span class="position-absolute top-2 icon-2 px-3 d-flex align-items-center search-icon">
243 @ReadFile(iconPath + "search.svg")
244 </span>
245
246 <input type="text" class="form-control rounded-0 py-2 ps-5 pe-3" id="filter" placeholder="@Translate("Enter city state or zip")">
247 </div>
248 <div class="stores-wrap vh-75 overflow-auto">
249 <div id="stores" class="list-group">
250 <!-- Store items will be populated here -->
251 </div>
252 </div>
253 </div>
254 }
255 else if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle"))
256 {
257 <div class="g-col-12 order-5 order-lg-3">
258 @headingLevelStart
259 @Model.Item.GetString("Title")
260 @headingLevelStop
261 </div>
262 }
263 </div>
264 }
265 else
266 {
267 <div class="alert alert-info" role="alert">
268 @Translate("Google maps API key is missing")
269 </div>
270 }
271
272 <script>
273 var defaultLat = @(defaultLat);
274 var defaultLng = @(defaultLng);
275 var initialZoomLevel = @(initialZoomLevel);
276 var markerPrimary = '@(DealersButtonMarker)';
277
278 var stores = [
279 @foreach (var location in locationList)
280 {
281 string LocationTent = GetCustomField(location, "AccessUser_FilterTents");
282 string LocationTentShowroom = GetCustomField(location, ShowByField);
283 string LocationAwning = GetCustomField(location, "AccessUser_FilterMotorhomes");
284 string LocationAwningShowroom = GetCustomField(location, "AccessUser_DisplayMotorhomes");
285
286 string WebsiteUrl = GetCustomField(location, WebsiteField);
287
288 string locationLatitude = location.GeolocationLatitude.ToString().Replace(",", ".");
289 if(locationLatitude == "0") { continue; }
290
291 <text>{
292 id: "@(location.ID)",
293 name: "@(location.Name.Trim())",
294 address: "@(location.Address.Trim())",
295 city: "@(location.City.Trim())",
296 zip: "@(location.Zip.Trim())",
297 state: "@(location.State.Trim())",
298 country: "@(location.Country.Trim())",
299 phone: "@(Translate("Tlf.")) @(location.Phone.Trim())",
300 web: "@(WebsiteUrl)",
301 tent: @(LocationTent == "1" ? "true" : "false"),
302 tentshowroom: @(LocationTentShowroom == "2" ? "true" : "false"),
303 awning: @(LocationAwning == "1" ? "true" : "false"),
304 awningshowroom: @(LocationAwningShowroom == "2" ? "true" : "false"),
305 lat: @(location.GeolocationLatitude.ToString().Replace(",", ".").Replace("\u2212", "-")),
306 lng: @(location.GeolocationLongitude.ToString().Replace(",", ".").Replace("\u2212", "-"))
307 },</text>
308 }
309 ];
310 </script>
311 <script src="https://maps.googleapis.com/maps/api/js?key=@(apiKey)&libraries=marker,places,geometry"></script>
312 <script src="https://unpkg.com/@@googlemaps/markerclusterer/dist/index.min.js"></script>
313 <script src="/Files/Templates/Designs/Swift/Assets/js/store-locator.js"></script>