Ejemplo n.º 1
0
        public async Task <IActionResult> Create()
        {
            var site = await GetCurrentSiteAsync();

            var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

            PageTitle = "Create Challenge";

            var viewModel = new ChallengesDetailViewModel
            {
                BadgeMakerUrl     = GetBadgeMakerUrl(siteUrl, site.FromEmailAddress),
                UseBadgeMaker     = true,
                IgnorePointLimits = UserHasPermission(Permission.IgnorePointLimits),
                MaxPointLimit     = await _challengeService.GetMaximumAllowedPointsAsync(site.Id)
            };

            viewModel = await GetDetailLists(viewModel);

            if (viewModel.MaxPointLimit.HasValue)
            {
                viewModel.MaxPointsMessage = $"(Up to {viewModel.MaxPointLimit.Value} points per required task)";
            }

            return(View(viewModel));
        }
Ejemplo n.º 2
0
        public async Task <IActionResult> Create()
        {
            var site = await GetCurrentSiteAsync();

            var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

            var viewModel = new TriggersDetailViewModel
            {
                Action           = "Create",
                IsSecretCode     = true,
                BadgeMakerUrl    = GetBadgeMakerUrl(siteUrl, site.FromEmailAddress),
                UseBadgeMaker    = true,
                EditAvatarBundle = UserHasPermission(Permission.ManageAvatars),
                EditMail         = UserHasPermission(Permission.ManageTriggerMail),
                EditVendorCode   = UserHasPermission(Permission.ManageVendorCodes),
                SystemList       = new SelectList((await _siteService.GetSystemList()), "Id", "Name"),
                BranchList       = new SelectList((await _siteService.GetAllBranches()), "Id", "Name"),
                ProgramList      = new SelectList((await _siteService.GetProgramList()), "Id", "Name")
            };

            if (viewModel.EditVendorCode)
            {
                viewModel.VendorCodeTypeList = new SelectList(
                    (await _vendorCodeService.GetTypeAllAsync()), "Id", "Description");
            }
            if (viewModel.EditAvatarBundle)
            {
                viewModel.UnlockableAvatarBundleList = new SelectList(
                    await _dynamicAvatarService.GetAllBundlesAsync(true), "Id", "Name");
            }

            PageTitle = "Create Trigger";
            return(View("Detail", viewModel));
        }
Ejemplo n.º 3
0
        public async Task <IActionResult> Avatar(string id)
        {
            var site = await GetCurrentSiteAsync();

            var filePath = _pathResolver.ResolveContentFilePath($"site{site.Id}/useravatars/{id}.png");

            if (System.IO.File.Exists(filePath))
            {
                var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

                var contentPath = _pathResolver.ResolveContentPath($"site{site.Id}/useravatars/{id}.png");
                var imageUrl    = Path.Combine(siteUrl, contentPath).Replace("\\", "/");
                var viewModel   = new ShareAvatarViewModel()
                {
                    CardDescription = site.AvatarCardDescription,
                    ImageUrl        = imageUrl,
                    PageUrl         = siteUrl + Request.Path
                };
                return(View(viewModel));
            }
            else
            {
                _logger.LogWarning($"No avatar found for id: {id}");
                TempData[TempDataKey.AlertDanger] = "Avatar not found.";
                return(RedirectToAction(nameof(HomeController.Index), "Home"));
            }
        }
Ejemplo n.º 4
0
        public async Task <IActionResult> Avatar(string id)
        {
            var site = await GetCurrentSiteAsync();

            var filePath = _pathResolver.ResolveContentFilePath($"site{site.Id}/useravatars/{id}.png");

            if (System.IO.File.Exists(filePath))
            {
                var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

                var contentPath = _pathResolver.ResolveContentPath($"site{site.Id}/useravatars/{id}.png");
                var imageUrl    = Path.Combine(siteUrl, contentPath).Replace("\\", "/");
                var viewModel   = new ShareAvatarViewModel()
                {
                    CardDescription = site.AvatarCardDescription,
                    ImageUrl        = imageUrl,
                    PageUrl         = siteUrl + Request.Path
                };
                return(View(viewModel));
            }
            else
            {
                return(NotFound());
            }
        }
Ejemplo n.º 5
0
        public async Task <IActionResult> GetIcs()
        {
            var site = await GetCurrentSiteAsync();

            var filename = new string(site.Name.Where(_ => char.IsLetterOrDigit(_)).ToArray());
            var siteUrl  = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

            var calendarBytes = await _siteService.GetIcsFile(siteUrl);

            return(File(calendarBytes, "text/calendar", $"{filename}.ics"));
        }
Ejemplo n.º 6
0
        public async Task <IActionResult> Detail(int id, string language)
        {
            var header = await _pageService.GetHeaderByIdAsync(id);

            var languages = await _languageService.GetActiveAsync();

            var selectedLanguage = languages
                                   .FirstOrDefault(_ => _.Name.Equals(language, StringComparison.OrdinalIgnoreCase))
                                   ?? languages.Single(_ => _.IsDefault);

            var page = await _pageService.GetByHeaderAndLanguageAsync(id, selectedLanguage.Id);

            var viewModel = new PageDetailViewModel
            {
                Page         = page,
                HeaderId     = header.Id,
                HeaderName   = header.PageName,
                HeaderStub   = header.Stub,
                NewPage      = page == null,
                LanguageList = new SelectList(languages, "Name", "Description",
                                              selectedLanguage.Name),
                SelectedLanguageId = selectedLanguage.Id
            };

            if (page?.IsPublished == true)
            {
                var baseUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

                var action = Url.Action("Index", "Info", new
                {
                    area    = "",
                    culture = selectedLanguage.Name,
                    id      = header.Stub
                });

                viewModel.PageUrl = baseUrl + action;
            }

            return(View(viewModel));
        }
Ejemplo n.º 7
0
        public async Task <IActionResult> Create()
        {
            var site = await GetCurrentSiteAsync();

            var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

            TriggersDetailViewModel viewModel = new TriggersDetailViewModel()
            {
                Action             = "Create",
                IsSecretCode       = true,
                BadgeMakerUrl      = GetBadgeMakerUrl(siteUrl, site.FromEmailAddress),
                UseBadgeMaker      = true,
                SystemList         = new SelectList((await _siteService.GetSystemList()), "Id", "Name"),
                BranchList         = new SelectList((await _siteService.GetAllBranches()), "Id", "Name"),
                ProgramList        = new SelectList((await _siteService.GetProgramList()), "Id", "Name"),
                VendorCodeTypeList = new SelectList(
                    (await _vendorCodeService.GetTypeAllAsync()), "Id", "Name")
            };

            PageTitle = "Create Trigger";
            return(View("Detail", viewModel));
        }
Ejemplo n.º 8
0
        public async Task <IActionResult> Create()
        {
            PageTitle = "Create Program";

            var site = await GetCurrentSiteAsync();

            var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

            var dailyLiteracyTipList = await _dailyLiteracyTipService.GetListAsync();

            var pointTranslationList = await _pointTranslationService.GetListAsync();

            var viewModel = new ProgramDetailViewModel()
            {
                Action               = nameof(Create),
                BadgeMakerUrl        = GetBadgeMakerUrl(siteUrl, site.FromEmailAddress),
                UseBadgeMaker        = true,
                DailyLiteracyTipList = new SelectList(dailyLiteracyTipList, "Id", "Name"),
                PointTranslationList = new SelectList(pointTranslationList, "Id", "TranslationName")
            };

            return(View("Detail", viewModel));
        }
Ejemplo n.º 9
0
        public async Task <IActionResult> Create()
        {
            var site = await GetCurrentSiteAsync();

            var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

            PageTitle = "Create Challenge";


            ChallengesDetailViewModel viewModel = new ChallengesDetailViewModel()
            {
                BadgeMakerUrl = GetBadgeMakerUrl(siteUrl, site.FromEmailAddress),
                UseBadgeMaker = true
            };

            viewModel = await GetDetailLists(viewModel);

            if (site.MaxPointsPerChallengeTask.HasValue)
            {
                viewModel.MaxPointsMessage = $"(Up to {site.MaxPointsPerChallengeTask.Value} points per required task)";
            }

            return(View(viewModel));
        }
Ejemplo n.º 10
0
        public async Task <IActionResult> Edit(string stub)
        {
            try
            {
                var page = await _pageService.GetByStubAsync(stub, false);

                var baseUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

                PagesEditViewModel viewModel = new PagesEditViewModel()
                {
                    Page    = page,
                    CanEdit = UserHasPermission(Permission.EditPages),
                    PageUrl = $"{baseUrl}{Url.Action("Index", "Info", new { area = "", stub = page.Stub })}"
                };
                PageTitle = "Edit Page";
                return(View(viewModel));
            }
            catch (GraException gex)
            {
                ShowAlertWarning("Unable to view page: ", gex);
                return(RedirectToAction("Index"));
            }
        }
Ejemplo n.º 11
0
        public async Task <IActionResult> Avatar(string id)
        {
            if (await GetSiteSettingBoolAsync(SiteSettingKey.Avatars.DisableSharing))
            {
                return(NotFound());
            }

            var site = await GetCurrentSiteAsync();

            var filePath = _pathResolver
                           .ResolveContentFilePath($"site{site.Id}/useravatars/{id}.png");

            if (System.IO.File.Exists(filePath))
            {
                var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

                var contentPath = _pathResolver
                                  .ResolveContentPath($"site{site.Id}/useravatars/{id}.png");
                var imageUrl = Path.Combine(siteUrl, contentPath)
                               .Replace("\\", "/", StringComparison.OrdinalIgnoreCase);
                var viewModel = new ShareAvatarViewModel()
                {
                    ImageUrl = imageUrl,
                    Social   = new Domain.Model.Social
                    {
                        Description = site.AvatarCardDescription,
                        ImageLink   = imageUrl
                    }
                };
                return(View(viewModel));
            }
            else
            {
                return(NotFound());
            }
        }
Ejemplo n.º 12
0
        public async Task <IActionResult> Create(int?id, bool communityExperience = false)
        {
            PageTitle = communityExperience == true
                ? "Create Community Experience"
                : "Create Event";

            var requireSecretCode = await GetSiteSettingBoolAsync(
                SiteSettingKey.Events.RequireBadge);

            var systemList = await _siteService.GetSystemList(true);

            var locationList = await _eventService.GetLocations();

            var programList = await _siteService.GetProgramList();

            EventsDetailViewModel viewModel = new EventsDetailViewModel()
            {
                CanAddSecretCode = requireSecretCode ||
                                   UserHasPermission(Permission.ManageTriggers),
                CanManageLocations = UserHasPermission(Permission.ManageLocations),
                CanRelateChallenge = UserHasPermission(Permission.ViewAllChallenges),
                SystemList         = new SelectList(systemList, "Id", "Name"),
                LocationList       = new SelectList(locationList, "Id", "Name"),
                ProgramList        = new SelectList(programList, "Id", "Name"),
                IncludeSecretCode  = requireSecretCode,
                RequireSecretCode  = requireSecretCode
            };

            if (viewModel.CanAddSecretCode)
            {
                var site = await GetCurrentSiteAsync();

                var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

                viewModel.BadgeMakerUrl = GetBadgeMakerUrl(siteUrl, site.FromEmailAddress);
                viewModel.UseBadgeMaker = true;
            }

            if (id.HasValue)
            {
                try
                {
                    var graEvent = await _eventService.GetDetails(id.Value,
                                                                  viewModel.CanRelateChallenge);

                    if (!graEvent.ParentEventId.HasValue)
                    {
                        graEvent.ParentEventId = graEvent.Id;
                    }
                    viewModel.Event = graEvent;
                    viewModel.Event.RelatedTriggerId = null;
                    if (graEvent.AtBranchId.HasValue)
                    {
                        var branch = await _siteService.GetBranchByIdAsync(graEvent.AtBranchId.Value);

                        viewModel.SystemId   = branch.SystemId;
                        viewModel.BranchList = new SelectList(await _siteService
                                                              .GetBranches(viewModel.SystemId, true), "Id", "Name");
                    }
                }
                catch (GraException gex)
                {
                    ShowAlertWarning("Unable to copy event: ", gex);
                }
            }

            if (viewModel.BranchList == null)
            {
                viewModel.SystemId   = GetId(ClaimType.SystemId);
                viewModel.BranchList = new SelectList(await _siteService
                                                      .GetBranches(viewModel.SystemId, true), "Id", "Name");
            }
            if (communityExperience)
            {
                viewModel.NewCommunityExperience = true;
                viewModel.UseLocation            = true;
            }

            return(View(viewModel));
        }
        public async Task <IActionResult> Detail(int id)
        {
            Challenge challenge;

            try
            {
                challenge = await _challengeService.GetChallengeDetailsAsync(id);
            }
            catch (GraException gex)
            {
                ShowAlertWarning(gex.Message);
                return(await Index(httpStatus : System.Net.HttpStatusCode.NotFound));
            }
            var siteStage = GetSiteStage();

            if (!string.IsNullOrEmpty(challenge.BadgeFilename))
            {
                challenge.BadgeFilename = _pathResolver.ResolveContentPath(challenge.BadgeFilename);
            }

            bool isActive      = AuthUser.Identity.IsAuthenticated && siteStage == SiteStage.ProgramOpen;
            bool showCompleted = siteStage == SiteStage.ProgramOpen ||
                                 siteStage == SiteStage.ProgramEnded;

            var viewModel = new ChallengeDetailViewModel
            {
                Challenge                = challenge,
                BadgePath                = challenge.BadgeFilename,
                IsActive                 = isActive,
                IsLoggedIn               = AuthUser.Identity.IsAuthenticated,
                ShowCompleted            = showCompleted,
                Tasks                    = new List <TaskDetailViewModel>(),
                IsBadgeEarning           = challenge.BadgeId.HasValue,
                PointCountAndDescription = challenge.PointsAwarded == 1
                    ? _sharedLocalizer[Annotations.Info.PointSingular, challenge.PointsAwarded]
                    : _sharedLocalizer[Annotations.Info.PointsPlural, challenge.PointsAwarded],
                TaskCountAndDescription = challenge.TasksToComplete == 1
                    ? _sharedLocalizer[Annotations.Info.TaskSingular, challenge.TasksToComplete]
                    : _sharedLocalizer[Annotations.Info.TasksPlural, challenge.TasksToComplete]
            };

            var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

            foreach (var task in challenge.Tasks)
            {
                var taskModel = new TaskDetailViewModel
                {
                    Id          = task.Id,
                    IsCompleted = task.IsCompleted ?? false,
                    TaskType    = task.ChallengeTaskType.ToString(),
                    Url         = task.Url,
                    Title       = task.Title,
                    Author      = task.Author
                };
                if (taskModel.TaskType != "Book")
                {
                    taskModel.Description = CommonMark.CommonMarkConverter.Convert(task.Title);
                }
                if (!string.IsNullOrWhiteSpace(task.Filename))
                {
                    var contentPath = _pathResolver.ResolveContentPath(task.Filename);
                    taskModel.FilePath = $"{siteUrl}/{contentPath}";
                }
                viewModel.Tasks.Add(taskModel);
            }
            PageTitle = _sharedLocalizer[Annotations.Title.ChallengeDetails, challenge.Name];
            return(View(viewModel));
        }
Ejemplo n.º 14
0
        public async Task <IActionResult> Create(int?id, bool communityExperience = false)
        {
            PageTitle = "Create Event";

            var systemList = await _siteService.GetSystemList(true);

            var locationList = await _eventService.GetLocations();

            var programList = await _siteService.GetProgramList();

            EventsDetailViewModel viewModel = new EventsDetailViewModel()
            {
                CanAddSecretCode   = UserHasPermission(Permission.ManageTriggers),
                CanManageLocations = UserHasPermission(Permission.ManageLocations),
                SystemList         = new SelectList(systemList, "Id", "Name"),
                LocationList       = new SelectList(locationList, "Id", "Name"),
                ProgramList        = new SelectList(programList, "Id", "Name")
            };

            if (viewModel.CanAddSecretCode)
            {
                var site = await GetCurrentSiteAsync();

                var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

                viewModel.BadgeMakerUrl = GetBadgeMakerUrl(siteUrl, site.FromEmailAddress);
                viewModel.UseBadgeMaker = true;
            }

            if (id.HasValue)
            {
                var graEvent = await _eventService.GetDetails(id.Value);

                if (!graEvent.ParentEventId.HasValue)
                {
                    graEvent.ParentEventId = graEvent.Id;
                }
                viewModel.Event = graEvent;
                viewModel.Event.RelatedTriggerId = null;
                if (graEvent.AtBranchId.HasValue)
                {
                    var branch = await _siteService.GetBranchByIdAsync(graEvent.AtBranchId.Value);

                    viewModel.SystemId   = branch.SystemId;
                    viewModel.BranchList = new SelectList(await _siteService
                                                          .GetBranches(viewModel.SystemId, true), "Id", "Name");
                }
            }

            if (viewModel.BranchList == null)
            {
                viewModel.SystemId   = GetId(ClaimType.SystemId);
                viewModel.BranchList = new SelectList(await _siteService
                                                      .GetBranches(viewModel.SystemId, true), "Id", "Name");
            }
            if (communityExperience)
            {
                viewModel.NewCommunityExperience = true;
            }

            return(View(viewModel));
        }
Ejemplo n.º 15
0
        public async Task <IActionResult> UploadFile(IFormFile file)
        {
            if (UserHasPermission(Permission.EditChallenges) ||
                UserHasPermission(Permission.ManageDashboardContent) ||
                UserHasPermission(Permission.ManagePages))
            {
                if (file != null)
                {
                    try
                    {
                        var folderPath = Path.Combine($"site{GetCurrentSiteId()}",
                                                      UploadFilesPath);
                        var contentDir = _pathResolver.ResolveContentFilePath(folderPath);

                        if (!Directory.Exists(contentDir))
                        {
                            Directory.CreateDirectory(contentDir);
                        }

                        var filename = file.FileName;
                        while (System.IO.File.Exists(Path.Combine(contentDir, filename)))
                        {
                            filename = $"{Path.GetFileNameWithoutExtension(file.FileName)}_" +
                                       Path.GetRandomFileName().Replace(".", "") +
                                       Path.GetExtension(file.FileName);
                        }

                        var filePath = Path.Combine(contentDir, filename);

                        _logger.LogDebug("Writing out task file {TaskFile}", filePath);
                        using (var fileStream = file.OpenReadStream())
                        {
                            using (var ms = new MemoryStream())
                            {
                                fileStream.CopyTo(ms);
                                System.IO.File.WriteAllBytes(filePath, ms.ToArray());
                            }
                        }
                        var siteUrl = await _siteService.GetBaseUrl(Request.Scheme,
                                                                    Request.Host.Value);

                        var contentPath = _pathResolver.ResolveContentPath(Path.Combine(folderPath,
                                                                                        filename));
                        var fileUrl = Path.Combine(siteUrl, contentPath).Replace("\\", "/");

                        return(Json(fileUrl));
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"WMD fileupload error Type: {file.ContentType} Size: {file.Length} Exception: {ex}");
                        return(Json("Error"));
                    }
                }
                else
                {
                    return(Json("Empty"));
                }
            }
            else
            {
                return(Json("UnAuth"));
            }
        }
Ejemplo n.º 16
0
        public async Task <IActionResult> Share()
        {
            if (await GetSiteSettingBoolAsync(SiteSettingKey.Avatars.DisableSharing))
            {
                return(RedirectToAction(nameof(Index)));
            }

            PageTitle = _sharedLocalizer[Annotations.Title.ShareYourAvatar];
            var userAvatar = await _avatarService.GetUserAvatarAsync();

            if (userAvatar?.Count > 0)
            {
                var site = await GetCurrentSiteAsync();

                var directory = _pathResolver
                                .ResolveContentFilePath($"site{site.Id}/useravatars/");
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                var viewModel = new ShareViewModel();
                userAvatar = userAvatar.OrderBy(_ => _.AvatarItem.AvatarLayerPosition).ToList();
                using (var md5er = MD5.Create())
                {
                    var avatarBytes = userAvatar.Select(_ => _.Id)
                                      .SelectMany(BitConverter.GetBytes)
                                      .ToArray();
                    var encoded  = md5er.ComputeHash(avatarBytes);
                    var filename = Convert.ToBase64String(encoded).TrimEnd('=').Replace('+', '-')
                                   .Replace('/', '-');
                    viewModel.AvatarId = filename;
                    var path     = $"site{site.Id}/useravatars/{filename}.png";
                    var filePath = _pathResolver.ResolveContentFilePath(path);
                    if (!System.IO.File.Exists(filePath))
                    {
                        using (var image = new Image <Rgba32>(1200, 630))
                        {
                            var background = _pathResolver
                                             .ResolveContentFilePath($"site{site.Id}/avatarbackgrounds/background.png");
                            image.Mutate(_ => _.DrawImage(Image.Load(background), 1));

                            var avatarPoint = new Point(660, 60);
                            foreach (var element in userAvatar)
                            {
                                var file = _pathResolver.ResolveContentFilePath(element.Filename);
                                image.Mutate(_ => _.DrawImage(Image.Load(file), avatarPoint, 1));
                            }

                            await image.SaveAsPngAsync(filePath, new PngEncoder
                            {
                                CompressionLevel = PngCompressionLevel.BestCompression
                            });
                        }
                    }
                    var siteUrl = await _siteService.GetBaseUrl(Request.Scheme,
                                                                Request.Host.Value);

                    var contentPath = _pathResolver.ResolveContentPath(path);
                    viewModel.AvatarImageUrl = Path.Combine(siteUrl, contentPath)
                                               .Replace("\\", "/", StringComparison.OrdinalIgnoreCase);

                    var shareUrl = siteUrl + Url.Action(nameof(ShareController.Avatar), "Share")
                                   + $"/{filename}";
                    var facebookShareUrl = $"https://www.facebook.com/sharer/sharer.php?u={shareUrl}";
                    var twitterShareUrl  = $"https://twitter.com/intent/tweet?url={shareUrl}";
                    if (!string.IsNullOrWhiteSpace(site.TwitterAvatarMessage))
                    {
                        twitterShareUrl += $"&text={site.TwitterAvatarMessage}";
                    }
                    if (!string.IsNullOrWhiteSpace(site.TwitterAvatarHashtags))
                    {
                        twitterShareUrl += $"&hashtags={site.TwitterAvatarHashtags}";
                    }
                    if (!string.IsNullOrWhiteSpace(site.TwitterUsername))
                    {
                        twitterShareUrl += $"&via{site.TwitterUsername}";
                    }
                    viewModel.FacebookShareUrl = facebookShareUrl;
                    viewModel.TwitterShareUrl  = twitterShareUrl;
                }
                return(View(viewModel));
            }
            TempData[TempDataKey.AlertDanger]
                = _sharedLocalizer[Annotations.Validate.CustomizeAvatarFirst].ToString();
            return(RedirectToAction(nameof(Index)));
        }
Ejemplo n.º 17
0
        public async Task <IActionResult> Detail(int id)
        {
            Challenge challenge = new Domain.Model.Challenge();

            try
            {
                challenge = await _challengeService.GetChallengeDetailsAsync(id);
            }
            catch (GraException gex)
            {
                ShowAlertWarning("Unable to view challenge: ", gex);
                return(RedirectToAction("Index"));
            }
            var siteStage = GetSiteStage();

            if (!string.IsNullOrEmpty(challenge.BadgeFilename))
            {
                challenge.BadgeFilename = _pathResolver.ResolveContentPath(challenge.BadgeFilename);
            }

            bool isActive      = AuthUser.Identity.IsAuthenticated && siteStage == SiteStage.ProgramOpen;
            bool showCompleted = siteStage == SiteStage.ProgramOpen ||
                                 siteStage == SiteStage.ProgramEnded;

            ChallengeDetailViewModel viewModel = new ChallengeDetailViewModel()
            {
                Challenge     = challenge,
                BadgePath     = challenge.BadgeFilename,
                IsActive      = isActive,
                IsLoggedIn    = AuthUser.Identity.IsAuthenticated,
                ShowCompleted = showCompleted,
                Tasks         = new List <TaskDetailViewModel>()
            };

            viewModel.Details = $"Completing <strong>{challenge.TasksToComplete} "
                                + $"{(challenge.TasksToComplete > 1 ? "Tasks" : "Task")}</strong> will earn: "
                                + $"<strong>{challenge.PointsAwarded} "
                                + $"{(challenge.PointsAwarded > 1 ? "Points" : "Point")}</strong>";

            if (challenge.BadgeId.HasValue)
            {
                viewModel.Details += " and <strong>a badge</strong>.";
            }

            var siteUrl = await _siteService.GetBaseUrl(Request.Scheme, Request.Host.Value);

            foreach (var task in challenge.Tasks)
            {
                TaskDetailViewModel taskModel = new TaskDetailViewModel()
                {
                    Id          = task.Id,
                    IsCompleted = task.IsCompleted ?? false,
                    TaskType    = task.ChallengeTaskType.ToString(),
                    Url         = task.Url
                };
                var title = task.Title;
                if (!string.IsNullOrWhiteSpace(task.Url))
                {
                    title = $"<a href=\"{task.Url}\" target=\"_blank\">{title}</a>";
                }
                if (task.ChallengeTaskType.ToString() == "Book")
                {
                    string description = $"Read <strong><em>{title}</em></strong>";
                    if (!string.IsNullOrWhiteSpace(task.Author))
                    {
                        description += $" by <strong>{task.Author}</strong>";
                    }
                    taskModel.Description = description;
                }
                else
                {
                    taskModel.Description = CommonMark.CommonMarkConverter.Convert(task.Title);
                }
                if (!string.IsNullOrWhiteSpace(task.Filename))
                {
                    var contentPath = _pathResolver.ResolveContentPath(task.Filename);
                    taskModel.FilePath = $"{siteUrl}/{contentPath}";
                }
                viewModel.Tasks.Add(taskModel);
            }
            return(View(viewModel));
        }