- More than 20 years experience
- Complete assessments
- No agency fees
Interview with Jasper Fortuin – Managing Director WorldEmp India: Successfully collaborating with remote teams
In a world where technology is rapidly evolving, working with remote teams is increasingly becoming the norm. Companies are discovering the benefits of remote recruitment, particularly hiring permanent colleagues remotely.
But what makes these collaborations successful? And why do Dutch companies often choose remote recruitment in countries like India?
Background and experience of Jasper Fortuin
Jasper Fortuin, Managing Director at WorldEmp India, has extensive experience with remote recruitment and collaboration between Dutch and Indian colleagues. "From 2016 to 2021, I worked for KPN in India and witnessed hundreds of teams collaborating between the Netherlands and India. Since I joined WorldEmp in February 2023, I have met many colleagues and have been impressed by their technical and personal qualities. At WorldEmp, both large and small companies work with Indian colleagues in technical roles, and that collaboration is particularly successful."
"Understanding and acceptance of cultural differences are crucial. Indian colleagues must truly be part of the team."
The keys to success with remote teams: culture, engagement, and shared successes
What are the keys to success in working with remote teams? "Understanding and acceptance of cultural differences are essential," emphasizes Fortuin. "It’s important to build personal relationships, even virtually, and to truly make Indian colleagues part of the team. It doesn’t work if they are only given less popular tasks; at WorldEmp, we ensure challenging and interesting projects for everyone."
Fortuin shares an example of how joint celebrations strengthen a sense of teamwork. "We celebrate successes both in the Netherlands and in India. This can include shared breakfast sessions or distributing gifts in both countries. This way, Indian and Dutch colleagues feel equal, which is essential for effective collaboration."
Language and culture as challenges in Dutch-Indian collaborations
Why does collaboration between Dutch and Indian teams sometimes falter? According to Fortuin, this often stems from misunderstandings related to language and culture. "Many companies still communicate in Dutch, which can be challenging for Indian colleagues. Cultural differences also play a role. In India, for instance, there is a strong sense of hierarchy, making open feedback not always a given. At WorldEmp, we therefore screen candidates not only for technical skills but also for their ability to communicate proactively and clearly in a Dutch work environment."
He adds that Dutch directness sometimes clashes with the more reserved attitude of Indian employees, who often perceive their Dutch colleagues as clients. "This can hinder honest communication. That’s why we select candidates who are not only technically proficient but also fit well within the Dutch work culture and are confident enough to express themselves."
Free recruitment and 40-70% lower labor costs
In the long term, your company can easily scale up without risk by leveraging a large talent pool in countries with highly qualified professionals.
WorldEmp's rigorous selection: experienced remote professionals for sustainable collaboration
At WorldEmp, a strict selection process is applied to ensure successful collaborations with remote employees. "Our selection starts with a critical screening by the recruitment team and an interview with 'social assessors,'" explains Fortuin. "This is followed by cultural onboarding, and we remain closely involved even after the probationary period. This ensures that employees continue to develop and perform well within their teams."
This approach sets WorldEmp apart from other companies. "In India, many companies work with fixed KPIs and teams of recent graduates from a 'pool.' At WorldEmp, we select experienced professionals with at least six years of work experience. This leads to longer and more successful collaborations compared to standard recruitment agencies, where employees often drop out more quickly."
Communication and culture as the foundation for successful remote teams at WorldEmp
Fortuin emphasizes the importance of effective communication and cultural awareness in remote working. “Effective communication is crucial, especially when dealing with cultural differences. At WorldEmp, we continuously focus on communication through cultural training, all-hands meetings, and tailored coaching. Colleagues must feel safe to share their opinions without fear of repercussions.”
WorldEmp adopts a personal approach to managing these cultural aspects. “We regularly hold discussions with employees and take feedback from Dutch colleagues seriously. If a collaboration does not run smoothly, we investigate the cause and provide targeted support.”
Error executing template "Designs/ClientBase_generated/Paragraph/MultiColumnParagraph.cshtml" System.InvalidOperationException: Collection was modified; enumeration operation may not execute. at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) at System.Collections.Generic.List`1.Enumerator.MoveNextRare() at CompiledRazorTemplates.Dynamic.RazorEngine_9294ac8bf7c44dd6b896a36f566f32a6.<>c__DisplayClass9_0.<RenderContentArea>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Bluedesk\worldemp.cloud.dynamicweb-cms.com\files\Templates\Designs\ClientBase_generated\Paragraph\MultiColumnParagraph.cshtml:line 727 at CompiledRazorTemplates.Dynamic.RazorEngine_9294ac8bf7c44dd6b896a36f566f32a6.Execute() in D:\dynamicweb.net\Solutions\Bluedesk\worldemp.cloud.dynamicweb-cms.com\files\Templates\Designs\ClientBase_generated\Paragraph\MultiColumnParagraph.cshtml:line 668 at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 @using Dynamicweb; 3 @using Dynamicweb.Content.Items; 4 @using System.Web; 5 @using Bluedesk.Tools.DynamicWeb.ExtensionMethods; 6 @using Bluedesk.DynamicWeb.ItemTypes; 7 8 @using System.Runtime.Caching; 9 10 11 @{ 12 /* 13 var paragraphID = Pageview.CurrentParagraph.ID; 14 MultiColumnParagraph _data = Dynamicweb.Services.Items.GetItem("MultiColumnParagraph", Pageview.CurrentParagraph.ItemId).ToCodeFirstItem<MultiColumnParagraph>() ?? new MultiColumnParagraph(); 15 */ 16 17 var paragraphID = Pageview.CurrentParagraph.ID; 18 MultiColumnParagraph _data = new MultiColumnParagraph(); 19 20 int CacheTime = 5; 21 MemoryCache memCache = MemoryCache.Default; 22 string cacheKey = $"MultiColumnParagraph_{paragraphID}-{Pageview.AreaID}"; 23 24 if (Pageview.IsVisualEditorMode) 25 { 26 var cache = MemoryCache.Default; 27 memCache.Remove($"MultiColumnParagraph_{paragraphID}-{Pageview.AreaID}"); 28 } 29 30 if (memCache.Contains(cacheKey)) 31 { 32 _data = memCache.Get(cacheKey) as MultiColumnParagraph; 33 34 if (_data == null) 35 { 36 _data = Dynamicweb.Content.Services.Items.GetItem("MultiColumnParagraph", Pageview.CurrentParagraph.ItemId).ToCodeFirstItem<MultiColumnParagraph>() ?? new MultiColumnParagraph(); 37 memCache.Set(cacheKey, _data, DateTimeOffset.UtcNow.AddMinutes(CacheTime)); 38 39 } 40 41 } 42 else 43 { 44 _data = Dynamicweb.Content.Services.Items.GetItem("MultiColumnParagraph", Pageview.CurrentParagraph.ItemId).ToCodeFirstItem<MultiColumnParagraph>() ?? new MultiColumnParagraph(); 45 memCache.Set(cacheKey, _data, DateTimeOffset.UtcNow.AddMinutes(CacheTime)); 46 } 47 48 List<string> BackgroundConfigIdList = ((List<string>)Dynamicweb.Context.Current.Items["BackgroundConfigIdList"]) ?? new List<string>(); 49 BackgroundConfigIdList.Add(_data.BackgroundConfigurationID); 50 Dynamicweb.Context.Current.Items["BackgroundConfigIdList"] = BackgroundConfigIdList; 51 52 string ParagraphHeight = _data.Height == 0 ? "auto" : _data.Height + "px"; 53 string MobileParagraphHeight = _data.MobileHeight == 0 ? "auto" : _data.MobileHeight + "px"; 54 55 } 56 57 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 58 @using Dynamicweb; 59 @using Dynamicweb.Content.Items; 60 @using Bluedesk.DynamicWeb.ItemTypes; 61 62 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 63 @using Dynamicweb; 64 @using Dynamicweb.Content.Items; 65 @using Bluedesk.DynamicWeb.ItemTypes; 66 67 @functions { 68 69 Dictionary<string, string> GetFontConfiguration(string TextColor, FontConfigurationItemTab FontConfiguration) 70 { 71 var colorService = new ColorSwatchService(); 72 TextColor = !string.IsNullOrWhiteSpace(TextColor) ? TextColor : "" ; 73 TextColor = !TextColor.Contains("#") ? colorService.GetHexColor(Pageview.AreaID, TextColor) : TextColor; 74 Dictionary<string, string> FontConfig = new Dictionary<string, string>() { 75 { "textColor" , TextColor }, 76 { "fontSize" , FontConfiguration.FontSize }, 77 { "lineHeight", FontConfiguration.LineHeight}, 78 { "fontFamily" , FontConfiguration.FontConfiguration.FontFamily }, 79 { "fontWeight" , FontConfiguration.FontWeight }, 80 { "fontStyle" , FontConfiguration.FontStyle } 81 }; 82 return FontConfig; 83 } 84 85 public string GenerateButtonConfigVariables(ButtonConfiguration BC, MasterConfig mc, int areaId) 86 { 87 string ButtonLabelAlignment = BC.ButtonLabelAlignment; 88 switch (ButtonLabelAlignment) 89 { 90 case "align-left": 91 ButtonLabelAlignment = "flex-start"; 92 break; 93 case "align-center": 94 ButtonLabelAlignment = "center"; 95 break; 96 case "align-right": 97 ButtonLabelAlignment = "flex-end"; 98 break; 99 case "align-full": 100 ButtonLabelAlignment = "space-between"; 101 break; 102 default: 103 ButtonLabelAlignment = "flex-start"; 104 break; 105 } 106 107 var btnStyleBlock = new System.Text.StringBuilder(); 108 109 // General Config 110 btnStyleBlock.Append(GenerateCssVar("btn-min-height", $"{mc.GeneralConfiguration.ButtonHeight}px")); 111 btnStyleBlock.Append(GenerateCssVar("btn-border-radius", $"{mc.GeneralConfiguration.RoundedCornerValue}px")); 112 113 // Button Config 114 btnStyleBlock.Append(GenerateCssVar("btn-border-width", $"{BC.BorderSize.ToString()}px")); 115 btnStyleBlock.Append(GenerateCssVar("btn-label-alignment", ButtonLabelAlignment)); 116 117 // Button Config Tab 118 btnStyleBlock.Append(GenerateCssVar("btn-bg-color", BC.ButtonColorConfiguration.BackgroundColor.GetColorCode(areaId))); 119 btnStyleBlock.Append(GenerateCssVar("btn-font-color", BC.ButtonColorConfiguration.FontColor.GetColorCode(areaId))); 120 btnStyleBlock.Append(GenerateCssVar("btn-border-color", BC.ButtonColorConfiguration.BorderColor.GetColorCode(areaId))); 121 122 // Button Config Hover tab 123 btnStyleBlock.Append(GenerateCssVar("btn-bg-color-hover", BC.ButtonHoverColorConfiguration.BackgroundColor.GetColorCode(areaId))); 124 btnStyleBlock.Append(GenerateCssVar("btn-font-color-hover", BC.ButtonHoverColorConfiguration.FontColor.GetColorCode(areaId))); 125 btnStyleBlock.Append(GenerateCssVar("btn-border-color-hover", BC.ButtonHoverColorConfiguration.BorderColor.GetColorCode(areaId))); 126 127 // Button Config Font Config 128 btnStyleBlock.Append(GenerateCssVar("btn-font-size", BC.FontConfiguration.FontSize)); 129 btnStyleBlock.Append(GenerateCssVar("btn-font-config-color", BC.FontConfiguration.Color.GetColorCode(areaId))); 130 btnStyleBlock.Append(GenerateCssVar("btn-font-line-height", BC.FontConfiguration.LineHeight)); 131 btnStyleBlock.Append(GenerateCssVar("btn-font-family", BC.FontConfiguration.FontConfiguration.FontFamily)); 132 btnStyleBlock.Append(GenerateCssVar("btn-font-weight", BC.FontConfiguration.FontWeight)); 133 btnStyleBlock.Append(GenerateCssVar("btn-font-transform", BC.FontConfiguration.FontStyle)); 134 135 return btnStyleBlock.ToString(); 136 } 137 138 public string GenerateCssVar(string name, string value) 139 { 140 if (!string.IsNullOrWhiteSpace(value)) { 141 return $"--{name}: {value};"; 142 } else { 143 return ""; 144 } 145 } 146 } 147 148 149 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 150 @using Dynamicweb; 151 @using Dynamicweb.Content.Items; 152 @using Bluedesk.DynamicWeb.ItemTypes; 153 @using Bluedesk.DynamicWeb.ItemTypes.Configuration; 154 155 156 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 157 @using Dynamicweb; 158 @using Dynamicweb.Content.Items; 159 @using Bluedesk.DynamicWeb.ItemTypes; 160 @using Bluedesk.DynamicWeb.ItemTypes.Extensions; 161 @using Bluedesk.DynamicWeb.ItemTypes.Configuration; 162 @using Bluedesk.DynamicWeb.ItemTypes.Settings.Configuration; 163 @using Dynamicweb; 164 @using Dynamicweb.Frontend 165 @using Bluedesk.DynamicWeb.ItemTypes.BaseSolution; 166 167 @helper RenderButton(CTAButton button, PageView Pageview) 168 { 169 170 if (!string.IsNullOrWhiteSpace(button.GetLink(Pageview))) 171 { 172 string Template = button.GetButtonTemplate().Replace("{{ ButtonLink }}", button.GetLink(Pageview)); 173 @Template; 174 } 175 } 176 177 178 @{ 179 180 var colorService = new ColorSwatchService(); 181 182 string fullWidthContainerClass = _data.Fullwidth ? "" : "container"; 183 184 string backgroundClass = !string.IsNullOrWhiteSpace(_data.BackgroundConfiguration.BackgroundClass) ? string.Format("bg-{0}", _data.BackgroundConfiguration.BackgroundClass) : ""; 185 string backgroundStyle = !string.IsNullOrWhiteSpace(_data.BackgroundConfiguration.BackgroundColor) ? $"background-color: {_data.BackgroundConfiguration.BackgroundColor}; " : ""; 186 backgroundStyle += !string.IsNullOrWhiteSpace(_data.BackgroundConfiguration.BackgroundImage) ? $"background-image: url({_data.BackgroundConfiguration.BackgroundImage}); " : ""; 187 188 // string backgroundClass = "null"; 189 // string backgroundStyle = ""; 190 } 191 192 193 @functions { 194 //string getbackgroundclass(string backgroundClass) 195 //{ 196 // return !string.IsNullOrWhiteSpace(backgroundClass) ? string.Format("bg-{0}", backgroundClass) : ""; 197 //} 198 } 199 200 @helper CTAParagraphImage( 201 ParagraphImageResizable Image, 202 bool hasContent, 203 bool ImageAsBackground, 204 string ImagePosition, 205 bool ParallaxImage, 206 bool Fullwidth, 207 string imagesHeight, 208 double ColumnWidthSize, 209 int AnimationDuration = 300, 210 bool AnimateHalfBlock = false 211 ) 212 { 213 if (!string.IsNullOrWhiteSpace(Image.Image)) 214 { 215 216 string image = !string.IsNullOrWhiteSpace(Image.Image) ? Image.Image : null; 217 imagesHeight = hasContent ? imagesHeight : "100%"; 218 imagesHeight = !string.IsNullOrWhiteSpace(imagesHeight) ? "height: " + imagesHeight + ";" : ""; 219 220 string imageParrallax = ParallaxImage ? "rellax" : ""; 221 string imageAsBackground = ImageAsBackground ? "cta-paragraph__image--is-background" : ""; 222 double imageWidth = 2000; 223 224 imageWidth = Fullwidth ? imageWidth : 1200; 225 imageWidth = !ImageAsBackground ? imageWidth * ColumnWidthSize : imageWidth; 226 227 string strImageWidth = imageWidth + "px"; 228 string strImageWidthSize = imageWidth + "w"; 229 230 string ImageUrl; 231 if (image.EndsWith(".gif")) 232 { 233 ImageUrl = image; 234 } 235 else 236 { 237 ImageUrl = "/Admin/Public/GetImage.ashx?Image=" + image + "&Crop=7&Format=webp&Quality=90&Compression=80"; 238 ImageUrl = ImageUrl.Replace("?x", "&x"); 239 } 240 241 string animationDirection = AnimateHalfBlock ? ImagePosition.Equals("right") ? "fade-left" : "fade-right" : ""; 242 243 if (!string.IsNullOrWhiteSpace(Image.Image)) 244 { 245 246 <figure class="cta-paragraph__image-container @imageAsBackground @Image.PositionY @Image.PositionX" style="@imagesHeight" data-aos="@animationDirection" data-aos-duration="@AnimationDuration"> 247 248 <picture class="cta-paragraph__image @Image.BackgroundSize @imageParrallax"> 249 @if (ImageUrl.EndsWith(".gif")) 250 { 251 <source media="(max-width: 400px)" srcset="@ImageUrl&Width=400"> 252 <source media="(max-width: 994px)" srcset="@ImageUrl&Width=994"> 253 <img src="@ImageUrl" loading="lazy" alt="@Image.ImageAlt" class="cta-paragraph__image @Image.BackgroundSize @imageParrallax" width="1980" height="500"> 254 } 255 else 256 { 257 <source media="(max-width: 400px)" srcset="@ImageUrl&Width=400"> 258 <source media="(max-width: 994px)" srcset="@ImageUrl&Width=994"> 259 <img src="@ImageUrl&Width=@imageWidth" loading="lazy" alt="@Image.ImageAlt" class="cta-paragraph__image @Image.BackgroundSize @imageParrallax" width="1980" height="500"> 260 } 261 </picture> 262 263 </figure> 264 } 265 } 266 } 267 268 @helper CTAParagraphContent( 269 int paragraphID, 270 ParagraphHeader Header, 271 ParagraphHeader SubHeader, 272 ParagraphContent Content, 273 CTAButton Button, 274 CTAButton ExtraButton, 275 ParagraphImage Image, 276 bool strCenterVertical, 277 string ImagePosition = "", 278 int AnimationDuration = 300, 279 bool AnimateHalfBlock = false 280 ) 281 { 282 283 bool hasImage = !string.IsNullOrWhiteSpace(Image.Image) ? true : false; 284 string noImageClass = hasImage ? "" : "no-image"; 285 286 string centerTextClass = strCenterVertical ? "text-center" : ""; 287 string centerContent = !string.IsNullOrWhiteSpace(Image.Image) ? "" : "cta-paragraph__content--center"; 288 289 string paragraphInstanceClass = "cta-paragraph__content--" + paragraphID; 290 291 string animationDirection = (AnimateHalfBlock && hasImage) ? ImagePosition.Equals("right") ? "fade-right" : "fade-left" : ""; 292 293 if (!string.IsNullOrWhiteSpace(Button.ButtonText) || !string.IsNullOrWhiteSpace(Content.Text) || !string.IsNullOrWhiteSpace(Header.HeaderFormatted("cta-paragraph__header"))) 294 { 295 296 <section class="cta-paragraph__content @paragraphInstanceClass @centerContent @noImageClass" data-aos="@animationDirection" data-aos-duration="@AnimationDuration"> 297 298 <article class="cta-paragraph__content-container @noImageClass"> 299 300 @if (!string.IsNullOrWhiteSpace(Header.HeaderFormatted("cta-paragraph__header"))) 301 { 302 <header class="cta-paragraph__header @centerTextClass"> 303 @if (SubHeader != null) 304 { 305 @SubHeader.HeaderFormatted("cta-paragraph__subheader") 306 } 307 @Header.HeaderFormatted("cta-paragraph__header") 308 </header> 309 } 310 311 @if (!string.IsNullOrWhiteSpace(Content.Text)) 312 { 313 <div class="cta-paragraph__text @centerTextClass">@Content.Text</div> 314 } 315 316 @if (!string.IsNullOrWhiteSpace(Button.GetLink(Pageview)) && !string.IsNullOrWhiteSpace(Button.ButtonText)) 317 { 318 <nav class="cta-paragraph__btn-navigation @centerTextClass"> 319 @RenderButton(Button, Pageview) 320 @RenderButton(ExtraButton, Pageview) 321 </nav> 322 } 323 324 </article> 325 </section> 326 327 } 328 329 } 330 331 @helper CTAParagraphVideo(ParagraphVideo Video, string imagesHeight) 332 { 333 if (!string.IsNullOrWhiteSpace(Video.YoutubeLink) || !string.IsNullOrWhiteSpace(Video.VimeoLink)) 334 { 335 string YoutubeID = Video.YoutubeId; 336 string YoutubeLink = Video.YoutubeLink; 337 338 string VimeoID = Video.VimeoId; 339 string VimeoLink = Video.VimeoLink; 340 341 int CleanVideo = Video.Clean ? 1 : 0; 342 int ShowControls = Video.ShowControls ? 1 : 0; 343 int AutoPlay = Video.AutoPlay ? 1 : 0; 344 int LoopVideo = Video.LoopVideo ? 1 : 0; 345 int MuteAudio = Video.MuteAudio ? 1 : 0; 346 string hideControlsClass = Video.ShowControls ? "video-player-wrapper--hidecontrols" : ""; 347 string origin = Dynamicweb.Environment.Helpers.LinkHelper.GetHttpDomain(); 348 imagesHeight = !string.IsNullOrWhiteSpace(imagesHeight) ? "height: " + imagesHeight + ";" : ""; 349 350 if (!string.IsNullOrWhiteSpace(YoutubeLink)) 351 { 352 if(AutoPlay == 1) 353 { 354 <section class="cta-paragraph__video-container" style="@imagesHeight"> 355 <div class=""> 356 <div class="video-player-wrapper @hideControlsClass"> 357 <iframe class="video-player" loading="lazy" data-video="@YoutubeID" frameborder="0" allowfullscreen allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" title="YouTube video player" src="https://www.youtube-nocookie.com/embed/@YoutubeID?autoplay=@AutoPlay&controls=@ShowControls&loop=@LoopVideo&playlist=@YoutubeID&playsinline=1&modestbranding=@CleanVideo&mute=@MuteAudio&rel=0&enablejsapi=1&origin=@origin&disablekb=0"></iframe> 358 </div> 359 </div> 360 </section> 361 } 362 else 363 { 364 <lite-youtube videoid="@YoutubeID" params="controls=@ShowControls&loop=@LoopVideo&playlist=@YoutubeID&playsinline=1&modestbranding=@CleanVideo&mute=@MuteAudio&rel=0&enablejsapi=1&origin=@origin&disablekb=0"></lite-youtube> 365 } 366 } 367 if (!string.IsNullOrWhiteSpace(VimeoLink)) 368 { 369 <section class="cta-paragraph__video-container" style="@imagesHeight"> 370 <div class=""> 371 <div class="video-player-wrapper"> 372 <iframe class="video-player" loading="lazy" data-video="@VimeoID" frameborder="0" allowfullscreen allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" title="Vimeo video player" src="https://player.vimeo.com/video/@VimeoID?title=0&byline=0&portrait=0&autoplay=@AutoPlay&controls=@ShowControls&loop=@LoopVideo&muted=@MuteAudio"></iframe> 373 </div> 374 </div> 375 </section> 376 } 377 } 378 } 379 380 @helper CTAParagraphIcon(ParagraphIcon Icon, bool strCenterVertical) 381 { 382 if (!string.IsNullOrWhiteSpace(Icon.FaIcon)) 383 { 384 string centerIconClass = strCenterVertical ? "justify-center" : "justify-start"; 385 string iconSizeClass = string.Format("cta-paragraph__icon--{0}", Icon.FaIconSize); 386 387 <div class="cta-paragraph__icon-container"> 388 <div class="cta-paragraph__icon-inner-container @centerIconClass"> 389 <span class="cta-paragraph__icon @iconSizeClass">@Icon.FaIcon</span> 390 </div> 391 </div> 392 } 393 } 394 395 @helper RenderContentAlignment(BackgroundConfiguration data) 396 { 397 398 switch (data.ContentElementAlign) 399 { 400 case "align-left": 401 <text> 402 align-items: flex-start; 403 text-align: left; 404 </text> 405 break; 406 case "align-center": 407 <text> 408 align-items: center; 409 text-align: center; 410 </text> 411 break; 412 case "align-right": 413 <text> 414 align-items: flex-end; 415 text-align: right; 416 </text> 417 break; 418 case "align-full": 419 <text> 420 align-items: flex-start; 421 text-align: justify; 422 </text> 423 break; 424 } 425 426 } 427 428 429 @{ 430 431 string backgroundImageRepeatClass = _data.BackgroundConfiguration.BackgroundImageRepeat; 432 string backgroundImageSizeClass = ""; 433 434 string BackgroundImagePositionX = _data.BackgroundConfiguration.BackgroundImagePositionX; 435 string BackgroundImagePositionY = _data.BackgroundConfiguration.BackgroundImagePositionY; 436 437 string BackgroundImagePositionClass = ""; 438 439 if (backgroundImageRepeatClass == "no-repeat") 440 { 441 BackgroundImagePositionClass = BackgroundImagePositionY + "-" + BackgroundImagePositionX; 442 backgroundImageSizeClass = _data.BackgroundConfiguration.BackgroundImageSize; 443 } 444 445 string ctaBackgroundColor = _data.BackgroundConfiguration.BackgroundColor; 446 447 ctaBackgroundColor = colorService.GetHexColor(Pageview.AreaID, ctaBackgroundColor); 448 449 string BackgroundGradient = _data.BackgroundConfiguration.BackgroundGradient; 450 451 string contentBackgroundColor = _data.BackgroundConfiguration.contentBackgroundColor; 452 string contentBorderColor = _data.BackgroundConfiguration.contentBorderColor; 453 454 string contentBorderSize = _data.BackgroundConfiguration.contentBorderSize + "px"; 455 456 string contentGutterClass = _data.BackgroundConfiguration.contentGutter; 457 string BackgroundPadding = _data.BackgroundConfiguration.backgroundPadding; 458 459 bool Containerfit = _data.BackgroundConfiguration.ContainerFit == "Fit" ? true : false; 460 461 contentBackgroundColor = colorService.GetHexColor(Pageview.AreaID, contentBackgroundColor); 462 contentBorderColor = colorService.GetHexColor(Pageview.AreaID, contentBorderColor); 463 464 string AnimateDirection = !string.IsNullOrWhiteSpace(_data.AnimateDirection) ? _data.AnimateDirection : ""; 465 int AnimationDuration = _data.AnimateDuration; 466 string DataAosValue = ""; 467 468 switch (AnimateDirection) 469 { 470 case "left": 471 DataAosValue = "fade-left"; 472 break; 473 474 case "right": 475 DataAosValue = "fade-right"; 476 break; 477 478 case "up": 479 DataAosValue = "fade-up"; 480 break; 481 482 case "down": 483 DataAosValue = "fade-down"; 484 break; 485 486 case "": 487 case "none": 488 // No action 489 break; 490 } 491 492 } 493 494 <style> 495 @_data.BackgroundConfiguration.Stylesheet 496 </style> 497 498 <style> 499 500 @@media screen and (max-width: 991px) { 501 .multicolumn--@paragraphID .multicolumn__item { 502 height: @MobileParagraphHeight !important; 503 } 504 } 505 506 @@media screen and (min-width: 991px) { 507 .multicolumn--@paragraphID .multicolumn__item { 508 height: @ParagraphHeight !important; 509 } 510 } 511 512 .multicolumn--@paragraphID { 513 background-color: @ctaBackgroundColor; 514 @if (!string.IsNullOrWhiteSpace(BackgroundGradient)) 515 { 516 @BackgroundGradient 517 } 518 } 519 520 .multicolumn--@paragraphID .cta-paragraph { 521 background-color: @contentBackgroundColor; 522 border: @contentBorderSize @contentBorderColor solid; 523 } 524 525 .multicolumn--@paragraphID .cta-paragraph__content-container 526 { 527 @RenderContentAlignment(_data.BackgroundConfiguration) 528 } 529 530 .multicolumn--@paragraphID .cta-paragraph__content { 531 @if (Containerfit) 532 { 533 <text> 534 flex-grow: 0; 535 </text> 536 } 537 } 538 539 .multicolumn--@paragraphID .cta-paragraph__image-container { 540 @if (Containerfit) 541 { 542 <text> 543 position: absolute; 544 top: 0; 545 left: 0; 546 right: 0; 547 bottom: 0; 548 </text> 549 } 550 } 551 552 .cta-paragraph--@paragraphID .cta-paragraph__btn-navigation { 553 @if (Containerfit) 554 { 555 556 switch (_data.BackgroundConfiguration.ContainerFitContentAlignment) 557 { 558 559 case "TopLeft": 560 case "MiddleLeft": 561 case "BottomLeft": 562 <text> 563 justify-content: flex-start; 564 </text> 565 break; 566 567 case "TopRight": 568 case "MiddleRight": 569 case "BottomRight": 570 <text> 571 justify-content: flex-end; 572 </text> 573 break; 574 575 576 case "TopCenter": 577 case "MiddleCenter": 578 case "BottomCenter": 579 <text> 580 justify-content: center; 581 </text> 582 break; 583 584 } 585 } 586 587 } 588 589 .multicolumn--@paragraphID .cta-paragraph { 590 @if (Containerfit) 591 { 592 593 switch (_data.BackgroundConfiguration.ContainerFitContentAlignment) { 594 case "TopLeft": 595 <text> 596 justify-content: flex-start; 597 align-items: flex-start; 598 </text> 599 break; 600 case "TopCenter": 601 <text> 602 justify-content: flex-start; 603 align-items: center; 604 </text> 605 break; 606 case "TopRight": 607 <text> 608 justify-content: flex-start; 609 align-items: flex-end; 610 </text> 611 break; 612 case "MiddleLeft": 613 <text> 614 justify-content: center; 615 align-items: flex-start; 616 </text> 617 break; 618 case "MiddleCenter": 619 <text> 620 justify-content: center; 621 align-items: center; 622 </text> 623 break; 624 case "MiddleRight": 625 <text> 626 justify-content: center; 627 align-items: flex-end; 628 </text> 629 break; 630 case "BottomLeft": 631 <text> 632 justify-content: flex-end; 633 align-items: flex-start; 634 </text> 635 break; 636 case "BottomCenter": 637 <text> 638 justify-content: flex-end; 639 align-items: center; 640 </text> 641 break; 642 case "BottomRight": 643 <text> 644 justify-content: flex-end; 645 align-items: flex-end; 646 </text> 647 break; 648 649 } 650 651 652 } 653 654 } 655 656 </style> 657 658 @if (_data != null) 659 { 660 <div class="multicolumn multicolumn--@paragraphID @backgroundClass @backgroundImageRepeatClass @BackgroundImagePositionClass @backgroundImageSizeClass @contentGutterClass @BackgroundPadding @_data.CssClass" data-paragraphid="@paragraphID" id="@paragraphID" style="@backgroundStyle" data-aos="@DataAosValue" data-aos-duration="@AnimationDuration"> 661 662 <div class="multicolumn__container @fullWidthContainerClass"> 663 @if (!string.IsNullOrWhiteSpace(_data.Header.HeaderFormatted())) 664 { 665 <header class="multicolumn__header-wrapper">@_data.Header.HeaderFormatted("cta-paragraph__header")</header> 666 } 667 668 @RenderContentArea(_data, paragraphID) 669 </div> 670 671 </div> 672 } 673 674 @helper RenderContentArea(MultiColumnParagraph _data, int paragraphID) 675 { 676 677 if (_data.Paragraphs().Count > 0) 678 { 679 680 // string contentElementAlign = _data.BackgroundConfiguration.ContentElementAlign; 681 682 int colIndex = 0; 683 var colorService = new ColorSwatchService(); 684 685 string centerTextClass = _data.CenterText ? "items-center text-center" : "items-start text-left"; 686 string WarpElementsClass = !string.IsNullOrWhiteSpace(_data.WrapElements) ? _data.WrapElements : ""; 687 double ColumnWidthSize = 1; 688 689 bool Shadow = _data.BackgroundConfiguration.contentShadow; 690 string shadowClass = Shadow ? "contentShadow" : ""; 691 692 bool enableColumnAnimation = _data.AnimateDelayColumns; 693 string AnimateDirection = !string.IsNullOrWhiteSpace(_data.AnimateDirection) ? _data.AnimateDirection : ""; 694 int AnimationDuration = 0; 695 string DataAosValue = ""; 696 697 if (enableColumnAnimation) 698 { 699 AnimationDuration = _data.AnimateDuration; 700 switch (AnimateDirection) 701 { 702 case "left": 703 DataAosValue = "fade-left"; 704 break; 705 706 case "right": 707 DataAosValue = "fade-right"; 708 break; 709 710 case "up": 711 DataAosValue = "fade-up"; 712 break; 713 714 case "down": 715 DataAosValue = "fade-down"; 716 break; 717 718 case "": 719 case "none": 720 // No action 721 break; 722 } 723 } 724 725 <div class="grid-container @WarpElementsClass"> 726 727 @foreach (ParagraphColumn p in _data.Paragraphs()) 728 { 729 730 bool hasContent = !string.IsNullOrWhiteSpace(p.Button().ButtonText) || !string.IsNullOrWhiteSpace(p.Content().Text) || !string.IsNullOrWhiteSpace(p.Header().HeaderFormatted()); 731 string ImageContainerFixed = hasContent ? "cta-paragraph__image-container--fixed" : ""; 732 string imagesHeight = hasContent ? _data.ImageHeight.ToString() + "px" : "100%"; 733 imagesHeight = imagesHeight == "0px" ? "auto" : imagesHeight; 734 735 if (_data.BackgroundConfiguration.ContainerFit == "Fit") 736 { 737 imagesHeight = "auto"; 738 } 739 740 string newWindow = p.Button().NewWindow ? "target='_blank'" : ""; 741 string ariaLabel = !string.IsNullOrWhiteSpace(p.Button().ButtonAriaLabel) ? "aria-label='" + p.Button().ButtonAriaLabel + "'" : ""; 742 bool clickableBlock = !string.IsNullOrWhiteSpace(p.Button().GetLink(Pageview)) && _data.Clickable; 743 string clickableClass = clickableBlock ? "cta-paragraph__container--clickable" : ""; 744 745 ColumnWidthSize = GetColumnsize(p.LargeDevices); 746 747 var animationDelay = enableColumnAnimation ? colIndex * 100 : 0; 748 colIndex++; 749 750 <div class="multicolumn__item [email protected] [email protected] [email protected]" data-aos="@DataAosValue" data-aos-duration="@AnimationDuration" data-aos-delay="@animationDelay"> 751 752 <section class="cta-paragraph config--@_data.BackgroundConfigurationID @clickableClass @shadowClass"> 753 754 @CTAParagraphImage( 755 p.Image(), 756 hasContent, 757 false, 758 null, 759 false, 760 _data.Fullwidth, 761 imagesHeight, 762 ColumnWidthSize 763 ) 764 765 @CTAParagraphVideo( 766 p.Video(), 767 imagesHeight 768 ) 769 770 @CTAParagraphIcon( 771 p.Icon(), 772 _data.CenterText 773 ) 774 775 @CTAParagraphContent( 776 paragraphID, 777 p.Header(), 778 p.Subheader(), 779 p.Content(), 780 p.Button(), 781 p.ExtraButton(), 782 p.Image(), 783 _data.CenterText 784 ) 785 786 @if (clickableBlock) 787 { 788 <a href="@p.Button().GetLink(Pageview)" class="cta-paragraph__clickable" @newWindow @ariaLabel></a> 789 } 790 791 </section> 792 </div> 793 } 794 </div> 795 } 796 797 } 798 799 800 @functions{ 801 802 double GetColumnsize(string DesktopColumnSize) 803 { 804 805 double ColumnWidthSize = 1; 806 807 switch (DesktopColumnSize) 808 { 809 case "auto": 810 ColumnWidthSize = 1; 811 break; 812 813 case "25p": 814 ColumnWidthSize = 0.25; 815 break; 816 817 case "33p": 818 ColumnWidthSize = 0.33; 819 break; 820 821 case "50p": 822 ColumnWidthSize = 0.5; 823 break; 824 825 case "66p": 826 ColumnWidthSize = 0.66; 827 break; 828 829 case "75p": 830 ColumnWidthSize = 0.75; 831 break; 832 833 case "full": 834 ColumnWidthSize = 1; 835 break; 836 } 837 838 return ColumnWidthSize; 839 840 } 841 842 843 // Check if this carousel contains only images (logo slider) 844 bool checkOnlyImages(Carousel _data) 845 { 846 847 int amountColumns = _data.CarouselItems.Count; // Amount of the columns in backend, filled by user 848 int emptyColumn = 0; 849 850 // Loop through all the columns 851 foreach (var column in _data.CarouselItems) 852 { 853 // If button is empty AND content is empty AND header is empty => this is img only 854 if (string.IsNullOrWhiteSpace(column.Button.ButtonText) && string.IsNullOrWhiteSpace(column.Content.Text) && string.IsNullOrWhiteSpace(column.Header.HeaderFormatted())) 855 { 856 emptyColumn++; 857 } 858 } 859 860 bool emptyColumnResult = emptyColumn == amountColumns ? true : false; 861 862 return emptyColumnResult; 863 864 } 865 } 866 867
Finally: learning from Indian culture and collaborating for growth
"India is a fascinating country," says Fortuin. "I learn more about the culture and collaboration with Indian colleagues every day. This deepens my understanding and helps with the cooperation."
For companies considering remote working, he has one final message: "With low unemployment and a housing shortage in the Netherlands, it is becoming increasingly difficult to find suitable talent. At WorldEmp, we offer a solution that works, and you can count on our support to make it a success."
INTERESTED? MORE INFORMATION?
Digital Knowledge Migrant with WorldEmp
At WorldEmp, we understand the challenges of finding qualified and highly skilled personnel. We offer a unique solution for companies looking to benefit from the advantages of a digital knowledge migrant without the usual pitfalls. Our approach is built on years of experience and a deep understanding of both the technological and human aspects of remote work.
Our services include recruiting and selecting highly qualified professionals from around the world. We ensure that every candidate is not only technically proficient but also a cultural fit for your company. This helps minimize communication issues and maintain strong team cohesion.
In addition, we provide comprehensive support in technology and tools. We ensure your team has access to the best tools for communication and collaboration, and we offer training and support to ensure everyone can use these tools effectively.